<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- saved from url=(0054)http://blog.csdn.net/lufeng20/article/details/24314381 -->
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript" async="" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/acom"></script>   
    
     
    <script type="text/javascript" async="" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/acom(1)"></script><script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/tracking.js" charset="utf-8"></script>  

    <script type="text/javascript">
        var protocol = window.location.protocol;
        document.write('<script type="text/javascript" src="' + protocol + '//csdnimg.cn/pubfooter/js/repoAddr2.js?v=' + Math.random() + '"></' + 'script>');
    </script><script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/repoAddr2.js"></script>

  
 <meta http-equiv="Cache-Control" content="no-siteapp"><link rel="alternate" media="handheld" href="http://blog.csdn.net/lufeng20/article/details/24314381#">

    <title>彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。
        - 博客频道 - CSDN.NET</title>
    
    <meta name="description" content="Uses ShellAPI; 1、//最小化procedure TForm1.btn1Click(Sender: TObject);var  I, J, X, Y: Word;begin  //第一种：最小化在屏幕的左下角 ，不是常见的最小化 // W">
    <script src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/jquery.js" type="text/javascript"></script>
    <script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ad.js"></script>
        <!--new top-->
       
        <link rel="stylesheet" href="http://c.csdnimg.cn/public/common/toolbar/css/index.css">
        <!--new top-->

    <link rel="Stylesheet" type="text/css" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/style.css">
    <link id="RSSLink" title="RSS" type="application/rss+xml" rel="alternate" href="http://blog.csdn.net/lufeng20/rss/list">
    <link rel="shortcut icon" href="http://c.csdnimg.cn/public/favicon.ico">
    <link type="text/css" rel="stylesheet" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/nobg.css">
 


<script src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/share.js"></script><link rel="stylesheet" type="text/css" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/job_reco.css"><style type="text/css">.MathJax_Hover_Frame {border-radius: .25em; -webkit-border-radius: .25em; -moz-border-radius: .25em; -khtml-border-radius: .25em; box-shadow: 0px 0px 15px #83A; -webkit-box-shadow: 0px 0px 15px #83A; -moz-box-shadow: 0px 0px 15px #83A; -khtml-box-shadow: 0px 0px 15px #83A; border: 1px solid #A6D ! important; display: inline-block; position: absolute}
.MathJax_Hover_Arrow {position: absolute; width: 15px; height: 11px; cursor: pointer}
</style><style type="text/css">#MathJax_About {position: fixed; left: 50%; width: auto; text-align: center; border: 3px outset; padding: 1em 2em; background-color: #DDDDDD; color: black; cursor: default; font-family: message-box; font-size: 120%; font-style: normal; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; z-index: 201; border-radius: 15px; -webkit-border-radius: 15px; -moz-border-radius: 15px; -khtml-border-radius: 15px; box-shadow: 0px 10px 20px #808080; -webkit-box-shadow: 0px 10px 20px #808080; -moz-box-shadow: 0px 10px 20px #808080; -khtml-box-shadow: 0px 10px 20px #808080; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
.MathJax_Menu {position: absolute; background-color: white; color: black; width: auto; padding: 5px 0px; border: 1px solid #CCCCCC; margin: 0; cursor: default; font: menu; text-align: left; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; z-index: 201; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; -khtml-border-radius: 5px; box-shadow: 0px 10px 20px #808080; -webkit-box-shadow: 0px 10px 20px #808080; -moz-box-shadow: 0px 10px 20px #808080; -khtml-box-shadow: 0px 10px 20px #808080; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
.MathJax_MenuItem {padding: 1px 2em; background: transparent}
.MathJax_MenuArrow {position: absolute; right: .5em; color: #666666}
.MathJax_MenuActive .MathJax_MenuArrow {color: white}
.MathJax_MenuArrow.RTL {left: .5em; right: auto}
.MathJax_MenuCheck {position: absolute; left: .7em}
.MathJax_MenuCheck.RTL {right: .7em; left: auto}
.MathJax_MenuRadioCheck {position: absolute; left: .7em}
.MathJax_MenuRadioCheck.RTL {right: .7em; left: auto}
.MathJax_MenuLabel {padding: 1px 2em 3px 1.33em; font-style: italic}
.MathJax_MenuRule {border-top: 1px solid #DDDDDD; margin: 4px 3px}
.MathJax_MenuDisabled {color: GrayText}
.MathJax_MenuActive {background-color: #606872; color: white}
.MathJax_Menu_Close {position: absolute; width: 31px; height: 31px; top: -15px; left: -15px}
</style><style type="text/css">#MathJax_Zoom {position: absolute; background-color: #F0F0F0; overflow: auto; display: block; z-index: 301; padding: .5em; border: 1px solid black; margin: 0; font-weight: normal; font-style: normal; text-align: left; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; box-shadow: 5px 5px 15px #AAAAAA; -webkit-box-shadow: 5px 5px 15px #AAAAAA; -moz-box-shadow: 5px 5px 15px #AAAAAA; -khtml-box-shadow: 5px 5px 15px #AAAAAA; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
#MathJax_ZoomOverlay {position: absolute; left: 0; top: 0; z-index: 300; display: inline-block; width: 100%; height: 100%; border: 0; padding: 0; margin: 0; background-color: white; opacity: 0; filter: alpha(opacity=0)}
#MathJax_ZoomFrame {position: relative; display: inline-block; height: 0; width: 0}
#MathJax_ZoomEventTrap {position: absolute; left: 0; top: 0; z-index: 302; display: inline-block; border: 0; padding: 0; margin: 0; background-color: white; opacity: 0; filter: alpha(opacity=0)}
</style><style type="text/css">.MathJax_Preview {color: #888}
#MathJax_Message {position: fixed; left: 1em; bottom: 1.5em; background-color: #E6E6E6; border: 1px solid #959595; margin: 0px; padding: 2px 8px; z-index: 102; color: black; font-size: 80%; width: auto; white-space: nowrap}
#MathJax_MSIE_Frame {position: absolute; top: 0; left: 0; width: 0px; z-index: 101; border: 0px; margin: 0px; padding: 0px}
.MathJax_Error {color: #CC0000; font-style: italic}
</style><link href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/bdsstyle.css" rel="stylesheet" type="text/css"><script type="text/javascript" charset="utf-8" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/main.js"></script><link rel="stylesheet" type="text/css" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/style(1).css"><link type="text/css" rel="stylesheet" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/style(2).css"><script src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/logger.js"></script><link rel="stylesheet" href="http://bdimg.share.baidu.com/static/api/css/share_style0_16.css?v=8277c65b.css"></head>
<body><div id="BAIDU_DUP_fp_wrapper" style="position: absolute; left: -1px; bottom: -1px; z-index: 0; width: 0px; height: 0px; overflow: hidden; visibility: hidden; display: none;"><iframe id="BAIDU_DUP_fp_iframe" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/o.html" style="width: 0px; height: 0px; visibility: hidden; display: none;"></iframe></div><iframe frameborder="0" style="display: none;"></iframe><div id="MathJax_Message" style="display: none;"></div>
    
   
      <!--new top-->
    <script id="toolbar-tpl-scriptId" fixed="true" prod="blog" skin="black" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/html.js" type="text/javascript"></script><div class="csdn-toolbar csdn-toolbar-skin-black ">        <div class="container row center-block ">          <div class="col-md-3 pull-left logo clearfix"><a href="http://www.csdn.net/?ref=toolbar" title="CSDN首页" target="_blank" class="icon"></a><a title="频道首页" href="http://blog.csdn.net/?ref=toolbar_logo" class="img blog-icon"></a></div>          <div class="pull-right login-wrap unlogin">            <ul class="btns">              <li class="loginlink"><a href="https://passport.csdn.net/account/login?ref=toolbar" target="_top">登录&nbsp;</a>|<a target="_top" href="http://passport.csdn.net/account/mobileregister?ref=toolbar&action=mobileRegister">&nbsp;注册</a></li>              <li class="search">                <div class="icon on-search-icon">                  <div class="wrap">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <form action="http://so.csdn.net/search" method="get" target="_blank">                      <input type="hidden" value="toolbar" name="ref" accesskey="2">                      <div class="border">                        <input placeholder="搜索" type="text" value="" name="q" accesskey="2"><span class="icon-enter-sm"></span>                      </div>                    </form>                  </div>                </div>              </li>              <li class="favor">                <div class="icon on-favor-icon">                  <div class="wrap">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <div style="display:none;" class="favor-success"><span class="msg">收藏成功</span>                      <div class="btns"><span class="btn btn-primary ok">确定</span></div>                    </div>                    <div style="display:none;" class="favor-failed"><span class="icon-danger-lg"></span><span class="msg">收藏失败，请重新收藏</span>                      <div class="btns"><span class="btn btn-primary ok">确定</span></div>                    </div>                    <form role="form" class="form-horizontal favor-form">                      <div class="form-group">                        <div class="clearfix">                          <label for="input-title" class="col-sm-2 control-label">标题</label>                          <div class="col-sm-10">                            <input id="inputTitle" type="text" placeholder="" class="title form-control">                          </div>                        </div>                        <div class="alert alert-danger"><strong></strong>标题不能为空</div>                      </div>                      <div class="form-group">                        <label for="input-url" class="col-sm-2 control-label">网址</label>                        <div class="col-sm-10">                          <input id="input-url" type="text" placeholder="" class="url form-control">                        </div>                      </div>                      <div class="form-group">                        <label for="input-tag" class="col-sm-2 tag control-label">标签</label>                        <div class="col-sm-10">                          <input id="input-tag" type="text" class="form-control tag">                        </div>                      </div>                      <div class="form-group">                        <label for="input-description" class="description col-sm-2 control-label">摘要</label>                        <div class="col-sm-10">                          <textarea id="input-description" class="form-control description"></textarea>                        </div>                      </div>                      <div class="form-group">                        <div class="col-sm-offset-2 col-sm-10 ft">                          <div class="col-sm-4 pull-left">                            <div class="checkbox">                              <label>                                <input type="checkbox" name="share" checked="checked" class="share">公开                              </label>                            </div>                          </div>                          <div class="col-sm-8 pull-right favor-btns">                            <button type="button" class="cancel btn btn-default">取消</button>                            <button type="submit" class="submit btn btn-primary">收藏</button>                          </div>                        </div>                      </div>                    </form>                  </div>                </div>              </li>              <li class="notify">                <div style="display:none" class="number"></div>                <div style="display:none" class="icon-hasnotes-sm"></div>                <div id="header_notice_num"></div>                <div class="icon on-notify-icon">                  <div class="wrap">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <div id="note1" class="csdn_note">                      <div class="box"></div>                    <iframe src="about:block" frameborder="0" allowtransparency="true" style="z-index:-1;position:absolute;top:0;left:0;width:100%;height:100%;background:transparent"></iframe></div>                  </div>                </div>              </li>              <li class="ugc">                <div class="icon on-ugc-icon">                  <div class="wrap clearfix">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <dl>                      <dt><a href="http://geek.csdn.net/news/expert?ref=toolbar" target="_blank" class="p-news clearfix" style="display:none;"><em class="icon"></em><span>分享资讯</span></a></dt>                      <dt><a href="http://u.download.csdn.net/upload?ref=toolbar" target="_blank" class="p-doc clearfix"><em class="icon"></em><span>传PPT/文档</span></a></dt>                      <dt><a href="http://bbs.csdn.net/topics/new?ref=toolbar" target="_blank" class="p-ask clearfix"><em class="icon"></em><span>提问题</span></a></dt>                      <dt><a href="http://write.blog.csdn.net/postedit?ref=toolbar" target="_blank" class="p-blog clearfix"><em class="icon"></em><span>写博客</span></a></dt>                      <dt><a href="http://u.download.csdn.net/upload?ref=toolbar" target="_blank" class="p-src clearfix"><em class="icon"></em><span>传资源</span></a></dt>                      <dt><a href="https://code.csdn.net/projects/new?ref=toolbar" target="_blank" class="c-obj clearfix"><em class="icon"></em><span>创建项目</span></a></dt>                      <dt><a href="https://code.csdn.net/snippets/new?ref=toolbar" target="_blank" class="c-code clearfix"><em class="icon"></em><span>创建代码片</span></a></dt>                    </dl>                  </div>                </div>              </li>              <li class="profile">                <div class="icon on-profile-icon"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/100x100.jpg" class="curr-icon-img">                  <div class="wrap clearfix">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <div class="bd">                      <dl class="clearfix">                        <dt class="pull-left img"><a target="_blank" href="http://my.csdn.net/?ref=toolbar" class="avatar"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/100x100.jpg"></a></dt>                        <dd class="info" style="border: none;"><a target="_blank" href="http://my.csdn.net/?ref=toolbar" class="nickname"></a><a class="set-nick" href="https://passport.csdn.net/account/profile">设置昵称<span class="write-icon"></span></a><span class="dec"><a class="fill-dec" href="http://my.csdn.net/" target="_blank">编辑自我介绍，让更多人了解你<span class="write-icon"></span></a></span></dd>                      </dl>                    </div>                    <div class="ft clearfix"><a target="_blank" href="http://my.csdn.net/my/account/changepwd?ref=toolbar" class="pull-left"><span class="icon-cog"></span>帐号设置</a><a href="https://passport.csdn.net/account/logout?ref=toolbar" target="_top" class="pull-left" style="margin-left:132px; width:18px; height:27px; white-space:nowrap; overflow:hidden;"><span class="icon-signout"></span><span class="out">退出</span></a></div>                  </div>                </div>              </li>              <li class="apps">                <div id="chasnew123" class="hasnew" style="display: none;"></div>                <div id="cappsarea123" class="icon on-apps-icon">                  <div class="wrap clearfix">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                  <div class="detail">                    <dl>                      <dt>                        <h5>社区</h5>                      </dt>                      <dd> <a href="http://blog.csdn.net/?ref=toolbar" target="_blank">博客</a></dd>                      <dd> <a href="http://bbs.csdn.net/?ref=toolbar" target="_blank">论坛</a></dd>                      <dd> <a href="http://download.csdn.net/?ref=toolbar" target="_blank">下载</a></dd>                      <dd><a href="http://ask.csdn.net/?ref=toolbar" target="_blank">技术问答</a></dd>                      <dd><a href="http://geek.csdn.net/?ref=toolbar" target="_blank">极客头条</a></dd>                      <dd style="display:none"> <a href="http://hero.csdn.net/?ref=toolbar" target="_blank">英雄会</a></dd>                    </dl>                  </div>                  <div class="detail">                    <dl>                      <dt>                        <h5>服务</h5>                      </dt>                      <dd style="display:none"> <a href="http://job.csdn.net/?ref=toolbar" target="_blank">JOB<img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/new.gif" style="display: none; margin-top: -26px; width: 23px;"></a></dd>                      <dd> <a href="http://edu.csdn.net/?ref=toolbar" target="_blank">学院<img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/new.gif" style="display: none; margin-top: -26px; width: 23px;"></a></dd>                      <dd> <a href="https://code.csdn.net/?ref=toolbar" target="_blank">CODE</a></dd>                      <dd> <a href="http://huiyi.csdn.net/?ref=toolbar" target="_blank">活动</a></dd>                      <dd> <a href="http://www.csto.com/?ref=toolbar" target="_blank">CSTO</a></dd>                      <dd> <a href="http://mall.csdn.net/?ref=toolbar" target="_blank">C币兑换<img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/new.gif" style="display: none; margin-top: -26px; width: 23px;"></a></dd>                    </dl>                  </div>                  <div class="detail last">                    <dl>                      <dt>                        <h5>俱乐部</h5>                      </dt>                      <dd> <a href="http://cto.csdn.net/?ref=toolbar" target="_blank">CTO俱乐部</a></dd>                      <dd> <a href="http://student.csdn.net/?ref=toolbar" target="_blank">高校俱乐部</a></dd>                    </dl>                  </div>                </div>              </div>            </li>            </ul>          </div>        </div>    </div>
     <!--new top-->
    <div id="container">
        <div id="header">
    <div class="header">
        <div id="blog_title">
            <h2>
                <a href="http://blog.csdn.net/lufeng20">逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。</a></h2>
            <h3>Java!!知识之上是思想~~</h3>
            <div class="clear">
            </div>
        </div>
        <div class="clear">
        </div>
    </div>
</div>
<div id="navigator">
    <div class="navigator_bg">
    </div>
    <div class="navigator">
        <ul>
            
                <li id="btnContents"><a href="http://blog.csdn.net/lufeng20?viewmode=contents"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_mulu&#39;])">
                    <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_list.gif">目录视图</span></a></li>
                <li id="btnView"><a href="http://blog.csdn.net/lufeng20?viewmode=list"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_zhaiyao&#39;])">
                    <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_summary.gif">摘要视图</span></a></li>
                <li id="btnRss"><a href="http://blog.csdn.net/lufeng20/rss/list"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_RSS&#39;])">
                    <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_rss.gif">订阅</span></a></li>                

            </ul>
    </div>
</div>
<script type="text/javascript">
    var username = "lufeng20";
    var _blogger = username;
    var blog_address = "http://blog.csdn.net/lufeng20";
    var static_host = "http://static.blog.csdn.net";
    var currentUserName = "";  
</script>

        <div id="body">
            <div id="main">
                <div class="main">
                        <div class="ad_class">
<div class="notice tracking-ad" data-mod="popu_3"> 

<a href="http://huiyi.csdn.net/activity/product/goods_list?project_id=2741" target="_blank">
<font color="red">2016软考项目经理实战班
</font></a>
&nbsp;&nbsp;&nbsp;

<a href="http://edu.csdn.net/yearPromotion" target="_blank">
<font color="blue">学院周年礼-顶尖课程钜惠呈现
</font></a>
&nbsp;&nbsp;&nbsp;
<a href="http://huiyi.csdn.net/activity/product/goods_list?project_id=2792" target="_blank">
<font color="red">Hadoop英雄会—暨Hadoop 10周年生日大趴</font>
&nbsp;&nbsp;&nbsp;
</a><a href="http://blog.csdn.net/dba_huangzj/article/details/50469185" target="_blank">
<font color="blue">【博客专家】有奖试读—Windows PowerShell实战指南
</font></a>

</div>                        </div>
                        

<!--AdForward Begin:-->
<script type="text/javascript" ads-src="http://csdnim.qtmojo.com/main/s?user=csdn|blog|fumeiti&amp;db=csdnim&amp;border=0&amp;local=yes&amp;js=ie" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/AllyesDeliver.min.js" charset="gbk" id="allyes_ins_203bcee21" ads-outputs="0" ads-tid="1d1dc91d4_0"></script><div id="1d1dc91d4_0" style="padding:0;margin:0;border:0;"><script type="text/javascript" data-belong="allyes" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/s"></script><script type="text/javascript">
var cpro_id="u2392861";
(window["cproStyleApi"] = window["cproStyleApi"] || {})[cpro_id]={at:"3",rsi0:"300",rsi1:"250",pat:"17",tn:"baiduCustNativeAD_xuanfu",rss1:"#FFFFFF",conBW:"1",adp:"1",ptt:"0",titFF:"%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91",titFS:"14",rss2:"#000000",titSU:"0"}
</script>
<script src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/f.js" type="text/javascript"></script><div id="BAIDU_UNION__wrapper_u2392861_0" style="box-sizing: content-box; width: 311px; height: 286px; overflow: hidden; z-index: 2147483647; position: fixed; bottom: 10px; right: 10px;"><div style="box-sizing: content-box;width:300px;height:250px;padding:4px;border:#acacac 1px solid;overflow:hidden;position:absolute;left:0;top:25px;"><iframe id="BAIDU_UNION__wrapper_u2392861_0_iframe" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/acom(2).html" width="300" height="250" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" style="border:0; vertical-align:bottom;margin:0;" allowtransparency="true"></iframe></div><div id="BAIDU_UNION__wrapper_u2392861_0_closebtn" style="box-sizing: content-box;position:absolute;width:61px;height:20px;top:0;left:250px;margin:0;padding:0;margin-bottom:5px;cursor:pointer;overflow:hidden;"><div style="box-sizing: content-box;width:40px;height:20px;background-color:#999999;color:#fff;float:left;margin-right:1px;font-size:12px;font-family:微软雅黑;text-align: center;line-height:20px;">关闭</div><a style="maring:0;padding:0;display:inline-block;border:none;overflow:hidden;height:20px;line-height:20px;cursor:pointer;width:20px;background:url(&#39;http://cpro.baidustatic.com/cpro/ui/noexpire/img/2.0.1/xuanfu_close.png&#39;) no-repeat 0 0;margin-bottom:3px;float:left"></a></div></div><script type="text/javascript" data-belong="allyes" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/delay.min.js"></script><script type="text/javascript" data-belong="allyes" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/delay.min.js"></script><script type="text/javascript" data-belong="allyes" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/delay.min.js"></script><script type="text/javascript" data-belong="allyes" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/delay.min.js"></script><script type="text/javascript" data-belong="allyes" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/delay.min.js"></script></div>
<!--AdForward End-->

  
<link href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/comment1.css" type="text/css" rel="stylesheet">
<link href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/style1.css" type="text/css" rel="stylesheet">
<script language="JavaScript" type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/jquery.cookie.js"></script>
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/main(1).js"></script>
<link rel="stylesheet" href="http://static.blog.csdn.net/public/res-min/markdown_views.css?v=1.0">
<link rel="stylesheet" href="http://static.blog.csdn.net/css/category.css?v=1.0">
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/MathJax.js"></script>

  <script type="text/ecmascript">
      window.quickReplyflag = true;
           
            var isBole = false;
            
          
    </script>
<div id="article_details" class="details">
    <div class="article_title">   
         <span class="ico ico_type_Original"></span>


    <h1>
        <span class="link_title"><a href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET.html">
        彻底理解ThreadLocal            
        </a></span>
    </h1>
</div>

   

        <div class="article_manage clearfix">
        <div class="article_r">
            <span class="link_postdate">2014-04-22 16:59</span>
            <span class="link_view" title="阅读次数">57361人阅读</span>
            <span class="link_comments" title="评论次数"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_pinglun&#39;])">评论</a>(58)</span>
            <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle(&#39;彻底理解ThreadLocal&#39;,&#39;24314381&#39;);return false;" title="收藏" target="_blank">收藏</a></span>
             <span class="link_report"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" onclick="javascript:report(24314381,2);return false;" title="举报">举报</a></span>

        </div>
    </div>
      <div class="category clearfix">
        <div class="category_l">
           <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/category_icon.jpg">
            <span>分类：</span>
        </div>
        <div class="category_r">
                    <label onclick="GetCategoryArticles(&#39;952595&#39;,&#39;lufeng20&#39;,&#39;top&#39;,&#39;24314381&#39;);">
                        <span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_fenlei&#39;]);">J2EE &amp; SSH<em>（23）</em></span>
                      <img class="arrow-down" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/arrow_triangle _down.jpg" style="display:inline;">
                      <img class="arrow-up" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/arrow_triangle_up.jpg" style="display:none;">
                        <div class="subItem">
                            <div class="subItem_t"><a href="http://blog.csdn.net/lufeng20/article/category/952595" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
                            <ul class="subItem_l" id="top_952595">                            
                            </ul>
                        </div>
                    </label>                    
                    <label onclick="GetCategoryArticles(&#39;952594&#39;,&#39;lufeng20&#39;,&#39;top&#39;,&#39;24314381&#39;);">
                        <span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_fenlei&#39;]);">java<em>（36）</em></span>
                      <img class="arrow-down" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/arrow_triangle _down.jpg" style="display:inline;">
                      <img class="arrow-up" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/arrow_triangle_up.jpg" style="display:none;">
                        <div class="subItem">
                            <div class="subItem_t"><a href="http://blog.csdn.net/lufeng20/article/category/952594" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
                            <ul class="subItem_l" id="top_952594">                            
                            </ul>
                        </div>
                    </label>                    
        </div>
    </div>
    <script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/category.js"></script>  
        <div class="bog_copyright">         
            <p class="copyright_p">版权声明：本文为博主原创文章，未经博主允许不得转载。</p>
        </div>

  

  
  
     

<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-width:200px;padding:4px 10px;"><p style="text-align:right;margin:0;"><span style="float:left;">目录<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" title="系统根据文章中H1到H6标签自动生成文章目录">(?)</a></span><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" onclick="javascript:return openct(this);" title="展开">[+]</a></p><ol style="display:none;margin-left:14px;padding-left:14px;line-height:160%;"><li><a href="http://blog.csdn.net/lufeng20/article/details/24314381#t0">ThreadLocal是什么</a></li><li><a href="http://blog.csdn.net/lufeng20/article/details/24314381#t1">Thread同步机制的比较</a></li><li><a href="http://blog.csdn.net/lufeng20/article/details/24314381#t2">javalangThreadLocalT的具体实现</a></li><li><a href="http://blog.csdn.net/lufeng20/article/details/24314381#t3">小结</a></li><li><a href="http://blog.csdn.net/lufeng20/article/details/24314381#t4">后记</a></li></ol></div><div style="clear:both"></div><div id="article_content" class="article_content">

<h2><a name="t0"></a><strong>ThreadLocal是什么</strong></h2>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　早在JDK 1.2的版本中就提供java.lang.ThreadLocal，ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　当使用ThreadLocal维护变量时，ThreadLocal为每个使用该变量的线程提供独立的变量副本，所以每一个线程都可以独立地改变自己的副本，而不会影响其它线程所对应的副本。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　从线程的角度看，目标变量就象是线程的本地变量，这也是类名中“Local”所要表达的意思。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　所以，在Java中编写线程局部变量的代码相对来说要笨拙一些，因此造成线程局部变量没有在Java开发者中得到很好的普及。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
ThreadLocal的接口方法</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
ThreadLocal类接口很简单，只有4个方法，我们先来了解一下：</p>
<ul style="font-family:Arial; font-size:14px; line-height:26px">
<li>void set(Object value)设置当前线程的线程局部变量的值。</li></ul>
<ul style="font-family:Arial; font-size:14px; line-height:26px">
<li>public Object get()该方法返回当前线程所对应的线程局部变量。</li></ul>
<ul style="font-family:Arial; font-size:14px; line-height:26px">
<li>public void remove()将当前线程局部变量的值删除，目的是为了减少内存的占用，该方法是JDK 5.0新增的方法。需要指出的是，当线程结束后，对应该线程的局部变量将自动被垃圾回收，所以显式调用该方法清除线程的局部变量并不是必须的操作，但它可以加快内存回收的速度。</li></ul>
<ul style="font-family:Arial; font-size:14px; line-height:26px">
<li>protected Object initialValue()返回该线程局部变量的初始值，该方法是一个protected的方法，显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法，在线程第1次调用get()或set(Object)时才执行，并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。</li></ul>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　值得一提的是，在JDK5.0中，ThreadLocal已经支持泛型，该类的类名已经变为ThreadLocal&lt;T&gt;。API方法也相应进行了调整，新版本的API方法分别是void set(T value)、T get()以及T initialValue()。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　ThreadLocal是如何做到为每一个线程维护变量的副本的呢？其实实现的思路很简单：在ThreadLocal类中有一个Map，用于存储每一个线程的变量副本，Map中元素的键为线程对象，而值对应线程的变量副本。我们自己就可以提供一个简单的实现版本：</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 1122px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.test;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;TestNum&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;①通过匿名内部类覆盖ThreadLocal的initialValue()方法，指定初始值</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;ThreadLocal&lt;Integer&gt;&nbsp;seqNum&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ThreadLocal&lt;Integer&gt;()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Integer&nbsp;initialValue()&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="number">0</span><span>;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;②获取下一个序列值</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">int</span><span>&nbsp;getNextNum()&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;seqNum.set(seqNum.get()&nbsp;+&nbsp;<span class="number">1</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;seqNum.get();&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestNum&nbsp;sn&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;TestNum();&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;③&nbsp;3个线程共享sn，各自产生序列号</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestClient&nbsp;t1&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;TestClient(sn);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestClient&nbsp;t2&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;TestClient(sn);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestClient&nbsp;t3&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;TestClient(sn);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t1.start();&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t2.start();&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t3.start();&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;TestClient&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Thread&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;TestNum&nbsp;sn;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;TestClient(TestNum&nbsp;sn)&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.sn&nbsp;=&nbsp;sn;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;run()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;(</span><span class="keyword">int</span><span>&nbsp;i&nbsp;=&nbsp;</span><span class="number">0</span><span>;&nbsp;i&nbsp;&lt;&nbsp;</span><span class="number">3</span><span>;&nbsp;i++)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;④每个线程打出3个序列值</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">"thread["</span><span>&nbsp;+&nbsp;Thread.currentThread().getName()&nbsp;+&nbsp;</span><span class="string">"]&nbsp;--&gt;&nbsp;sn["</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;sn.getNextNum()&nbsp;+&nbsp;<span class="string">"]"</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_1_2387728" name="code" class="java" style="display: none;">package com.test;

public class TestNum {
	// ①通过匿名内部类覆盖ThreadLocal的initialValue()方法，指定初始值
	private static ThreadLocal&lt;Integer&gt; seqNum = new ThreadLocal&lt;Integer&gt;() {
		public Integer initialValue() {
			return 0;
		}
	};

	// ②获取下一个序列值
	public int getNextNum() {
		seqNum.set(seqNum.get() + 1);
		return seqNum.get();
	}

	public static void main(String[] args) {
		TestNum sn = new TestNum();
		// ③ 3个线程共享sn，各自产生序列号
		TestClient t1 = new TestClient(sn);
		TestClient t2 = new TestClient(sn);
		TestClient t3 = new TestClient(sn);
		t1.start();
		t2.start();
		t3.start();
	}

	private static class TestClient extends Thread {
		private TestNum sn;

		public TestClient(TestNum sn) {
			this.sn = sn;
		}

		public void run() {
			for (int i = 0; i &lt; 3; i++) {
				// ④每个线程打出3个序列值
				System.out.println("thread[" + Thread.currentThread().getName() + "] --&gt; sn["
						 + sn.getNextNum() + "]");
			}
		}
	}
}
</pre><br>
<br>
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
&nbsp;通常我们通过匿名内部类的方式定义ThreadLocal的子类，提供初始的变量值，如例子中①处所示。TestClient线程产生一组序列号，在③处，我们生成3个TestClient，它们共享同一个TestNum实例。运行以上代码，在控制台上输出以下的结果：</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
thread[Thread-0] --&gt; sn[1]<br>
thread[Thread-1] --&gt; sn[1]<br>
thread[Thread-2] --&gt; sn[1]<br>
thread[Thread-1] --&gt; sn[2]<br>
thread[Thread-0] --&gt; sn[2]<br>
thread[Thread-1] --&gt; sn[3]<br>
thread[Thread-2] --&gt; sn[2]<br>
thread[Thread-0] --&gt; sn[3]<br>
thread[Thread-2] --&gt; sn[3]
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
考察输出的结果信息，我们发现每个线程所产生的序号虽然都共享同一个TestNum实例，但它们并没有发生相互干扰的情况，而是各自产生独立的序列号，这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
<br>
</p>
<h2><a name="t1"></a>Thread同步机制的比较</h2>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　ThreadLocal和线程同步机制相比有什么优势呢？ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　在同步机制中，通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的，使用同步机制要求程序慎密地分析什么时候对变量进行读写，什么时候需要锁定某个对象，什么时候释放对象锁等繁杂的问题，程序设计和编写难度相对较大。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本，从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本，从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象，在编写多线程代码时，可以把不安全的变量封装进ThreadLocal。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　由于ThreadLocal中可以持有任何类型的对象，低版本JDK所提供的get()返回的是Object对象，需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题，在一定程度地简化ThreadLocal的使用，代码清单 9 2就使用了JDK 5.0新的ThreadLocal&lt;T&gt;版本。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　概括起来说，对于多线程资源共享的问题，同步机制采用了“以时间换空间”的方式，而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量，让不同的线程排队访问，而后者为每一个线程都提供了一份变量，因此可以同时访问而互不影响。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　Spring使用ThreadLocal解决线程安全问题我们知道在一般情况下，只有无状态的Bean才可以在多线程环境下共享，在Spring中，绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean（如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等）中非线程安全状态采用ThreadLocal进行处理，让它们也成为线程安全的状态，因为有状态的Bean就可以在多线程中共享了。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　一般的Web应用划分为展现层、服务层和持久层三个层次，在不同的层中编写对应的逻辑，下层通过接口向上层开放功能调用。在一般情况下，从接收请求到返回响应所经过的所有程序调用都同属于一个线程，如图9‑2所示：</p>
<p align="center" style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
<img title="通通透透理解ThreadLocal" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/liOsRM8PmNF4U.gif" alt="通通透透理解ThreadLocal" align="center" style="border:0px solid black; max-width:100%"></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　同一线程贯通三层这样你就可以根据需要，将一些非线程安全的变量以ThreadLocal存放，在同一次请求响应的调用线程中，所有关联的对象引用到的都是同一个变量。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　下面的实例能够体现Spring对有状态Bean的改造思路：</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
代码清单3 TestDao：非线程安全</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 3171px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.test;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.Connection;&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">import</span><span>&nbsp;java.sql.SQLException;&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.Statement;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;TestDao&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;Connection&nbsp;conn;</span><span class="comment">//&nbsp;①一个非线程安全的变量</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;addTopic()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;SQLException&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Statement&nbsp;stat&nbsp;=&nbsp;conn.createStatement();<span class="comment">//&nbsp;②引用非线程安全变量</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;…</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_2_8702184" name="code" class="java" style="display: none;">package com.test;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDao {
	private Connection conn;// ①一个非线程安全的变量

	public void addTopic() throws SQLException {
		Statement stat = conn.createStatement();// ②引用非线程安全变量
		// …
	}
}</pre><br>
<br>
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
<br>
</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
由于①处的conn是成员变量，因为addTopic()方法是非线程安全的，必须在使用时创建一个新TopicDao实例（非singleton）。下面使用ThreadLocal对conn这个非线程安全的“状态”进行改造：</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
代码清单4 TestDao：线程安全</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 3649px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.test;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.Connection;&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">import</span><span>&nbsp;java.sql.SQLException;&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.Statement;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;TestDaoNew&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;①使用ThreadLocal保存Connection变量</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;ThreadLocal&lt;Connection&gt;&nbsp;connThreadLocal&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ThreadLocal&lt;Connection&gt;();&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;Connection&nbsp;getConnection()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection，</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;并将其保存到线程本地变量中。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(connThreadLocal.get()&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;getConnection();&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connThreadLocal.set(conn);&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;conn;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">else</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;connThreadLocal.get();</span><span class="comment">//&nbsp;③直接返回线程本地变量</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;addTopic()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;SQLException&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;④从ThreadLocal中获取线程对应的Connection</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Statement&nbsp;stat&nbsp;=&nbsp;getConnection().createStatement();&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_3_2399702" name="code" class="java" style="display: none;">package com.test;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDaoNew {
	// ①使用ThreadLocal保存Connection变量
	private static ThreadLocal&lt;Connection&gt; connThreadLocal = new ThreadLocal&lt;Connection&gt;();

	public static Connection getConnection() {
		// ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection，
		// 并将其保存到线程本地变量中。
		if (connThreadLocal.get() == null) {
			Connection conn = getConnection();
			connThreadLocal.set(conn);
			return conn;
		} else {
			return connThreadLocal.get();// ③直接返回线程本地变量
		}
	}

	public void addTopic() throws SQLException {
		// ④从ThreadLocal中获取线程对应的Connection
		Statement stat = getConnection().createStatement();
	}
}</pre><br>
<p><br>
</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　不同的线程在使用TopicDao时，先判断connThreadLocal.get()是否是null，如果是null，则说明当前线程还没有对应的Connection对象，这时创建一个Connection对象并添加到本地线程变量中；如果不为null，则说明当前的线程已经拥有了Connection对象，直接使用就可以了。这样，就保证了不同的线程使用线程相关的Connection，而不会使用其它线程的Connection。因此，这个TopicDao就可以做到singleton共享了。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　当然，这个例子本身很粗糙，将Connection的ThreadLocal直接放在DAO只能做到本DAO的多个方法共享Connection时不发生线程安全问题，但无法和其它DAO共用同一个Connection，要做到同一事务多DAO共享同一Connection，必须在一个共同的外部类使用ThreadLocal保存Connection。</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
<br>
<br>
</p>
<p>ConnectionManager.java</p>
<p></p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 4468px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.test;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.Connection;&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">import</span><span>&nbsp;java.sql.DriverManager;&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.SQLException;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConnectionManager&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;ThreadLocal&lt;Connection&gt;&nbsp;connectionHolder&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ThreadLocal&lt;Connection&gt;()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">protected</span><span>&nbsp;Connection&nbsp;initialValue()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;<span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"jdbc:mysql://localhost:3306/test"</span><span>,&nbsp;</span><span class="string">"username"</span><span>,&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"password"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">catch</span><span>&nbsp;(SQLException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;conn;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;Connection&nbsp;getConnection()&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;connectionHolder.get();&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setConnection(Connection&nbsp;conn)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectionHolder.set(conn);&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_9_3421316" name="code" class="java" style="display: none;">package com.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionManager {

	private static ThreadLocal&lt;Connection&gt; connectionHolder = new ThreadLocal&lt;Connection&gt;() {
		@Override
		protected Connection initialValue() {
			Connection conn = null;
			try {
				conn = DriverManager.getConnection(
						"jdbc:mysql://localhost:3306/test", "username",
						"password");
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return conn;
		}
	};

	public static Connection getConnection() {
		return connectionHolder.get();
	}

	public static void setConnection(Connection conn) {
		connectionHolder.set(conn);
	}
}</pre><br>
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
<br>
</p>
<h2><a name="t2"></a>java.lang.ThreadLocal&lt;T&gt;的具体实现</h2>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
那么到底ThreadLocal类是如何实现这种“为每个线程提供不同的变量拷贝”的呢？先来看一下ThreadLocal的set()方法的源码是如何实现的：<br>
</p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 5204px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Sets&nbsp;the&nbsp;current&nbsp;thread's&nbsp;copy&nbsp;of&nbsp;this&nbsp;thread-local&nbsp;variable</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;to&nbsp;the&nbsp;specified&nbsp;value.&nbsp;&nbsp;Most&nbsp;subclasses&nbsp;will&nbsp;have&nbsp;no&nbsp;need&nbsp;to</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;override&nbsp;this&nbsp;method,&nbsp;relying&nbsp;solely&nbsp;on&nbsp;the&nbsp;{@link&nbsp;#initialValue}</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;method&nbsp;to&nbsp;set&nbsp;the&nbsp;values&nbsp;of&nbsp;thread-locals.</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;value&nbsp;the&nbsp;value&nbsp;to&nbsp;be&nbsp;stored&nbsp;in&nbsp;the&nbsp;current&nbsp;thread's&nbsp;copy&nbsp;of</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;thread-local.</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;set(T&nbsp;value)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t&nbsp;=&nbsp;Thread.currentThread();&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ThreadLocalMap&nbsp;map&nbsp;=&nbsp;getMap(t);&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(map&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.set(<span class="keyword">this</span><span>,&nbsp;value);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">else</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createMap(t,&nbsp;value);&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_4_666005" name="code" class="java" style="display: none;"> /**
     * Sets the current thread's copy of this thread-local variable
     * to the specified value.  Most subclasses will have no need to
     * override this method, relying solely on the {@link #initialValue}
     * method to set the values of thread-locals.
     *
     * @param value the value to be stored in the current thread's copy of
     *        this thread-local.
     */
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }</pre><br>
在这个方法内部我们看到，首先通过getMap(Thread t)方法获取一个和当前线程相关的ThreadLocalMap，然后将变量的值设置到这个ThreadLocalMap对象中，当然如果获取到的ThreadLocalMap对象为空，就通过createMap方法创建。<br>
<br>
<br>
线程隔离的秘密，就在于ThreadLocalMap这个类。ThreadLocalMap是ThreadLocal类的一个静态内部类，它实现了键值对的设置和获取（对比Map对象来理解），每个线程中都有一个独立的ThreadLocalMap副本，它所存储的值，只能被当前线程读取和修改。ThreadLocal类通过操作每一个线程特有的ThreadLocalMap副本，从而实现了变量访问在不同线程中的隔离。因为每个线程的变量都是自己特有的，完全不会有并发错误。还有一点就是，ThreadLocalMap存储的键值对中的键是this对象指向的ThreadLocal对象，而值就是你所设置的对象了。<br>
<br>
<br>
为了加深理解，我们接着看上面代码中出现的getMap和createMap方法的实现：<br>
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 5890px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;Get&nbsp;the&nbsp;map&nbsp;associated&nbsp;with&nbsp;a&nbsp;ThreadLocal.&nbsp;Overridden&nbsp;in</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;InheritableThreadLocal.</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;@param&nbsp;&nbsp;t&nbsp;the&nbsp;current&nbsp;thread</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;@return&nbsp;the&nbsp;map</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>ThreadLocalMap&nbsp;getMap(Thread&nbsp;t)&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;t.threadLocals;&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">/**</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;Create&nbsp;the&nbsp;map&nbsp;associated&nbsp;with&nbsp;a&nbsp;ThreadLocal.&nbsp;Overridden&nbsp;in</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;InheritableThreadLocal.</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;@param&nbsp;t&nbsp;the&nbsp;current&nbsp;thread</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;@param&nbsp;firstValue&nbsp;value&nbsp;for&nbsp;the&nbsp;initial&nbsp;entry&nbsp;of&nbsp;the&nbsp;map</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;@param&nbsp;map&nbsp;the&nbsp;map&nbsp;to&nbsp;store.</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">void</span><span>&nbsp;createMap(Thread&nbsp;t,&nbsp;T&nbsp;firstValue)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;t.threadLocals&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;ThreadLocalMap(</span><span class="keyword">this</span><span>,&nbsp;firstValue);&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_5_7187421" name="code" class="java" style="display: none;">    /**
     * Get the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param  t the current thread
     * @return the map
     */
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

    /**
     * Create the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the map
     * @param map the map to store.
     */
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }</pre><br>
接下来再看一下ThreadLocal类中的get()方法:<br>
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 6405px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_7" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;Returns&nbsp;the&nbsp;value&nbsp;in&nbsp;the&nbsp;current&nbsp;thread's&nbsp;copy&nbsp;of&nbsp;this</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;thread-local&nbsp;variable.&nbsp;&nbsp;If&nbsp;the&nbsp;variable&nbsp;has&nbsp;no&nbsp;value&nbsp;for&nbsp;the</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*&nbsp;current&nbsp;thread,&nbsp;it&nbsp;is&nbsp;first&nbsp;initialized&nbsp;to&nbsp;the&nbsp;value&nbsp;returned</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;by&nbsp;an&nbsp;invocation&nbsp;of&nbsp;the&nbsp;{@link&nbsp;#initialValue}&nbsp;method.</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;*&nbsp;@return&nbsp;the&nbsp;current&nbsp;thread's&nbsp;value&nbsp;of&nbsp;this&nbsp;thread-local</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">public</span><span>&nbsp;T&nbsp;get()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t&nbsp;=&nbsp;Thread.currentThread();&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ThreadLocalMap&nbsp;map&nbsp;=&nbsp;getMap(t);&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(map&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ThreadLocalMap.Entry&nbsp;e&nbsp;=&nbsp;map.getEntry(<span class="keyword">this</span><span>);&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(e&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;(T)e.value;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;setInitialValue();&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_6_9216499" name="code" class="java" style="display: none;">    /**
     * Returns the value in the current thread's copy of this
     * thread-local variable.  If the variable has no value for the
     * current thread, it is first initialized to the value returned
     * by an invocation of the {@link #initialValue} method.
     *
     * @return the current thread's value of this thread-local
     */
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }</pre><br>
再来看setInitialValue()方法：
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
</p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 6850px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_8" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Variant&nbsp;of&nbsp;set()&nbsp;to&nbsp;establish&nbsp;initialValue.&nbsp;Used&nbsp;instead</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;of&nbsp;set()&nbsp;in&nbsp;case&nbsp;user&nbsp;has&nbsp;overridden&nbsp;the&nbsp;set()&nbsp;method.</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;the&nbsp;initial&nbsp;value</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;T&nbsp;setInitialValue()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;value&nbsp;=&nbsp;initialValue();&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t&nbsp;=&nbsp;Thread.currentThread();&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ThreadLocalMap&nbsp;map&nbsp;=&nbsp;getMap(t);&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(map&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;map.set(<span class="keyword">this</span><span>,&nbsp;value);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">else</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;createMap(t,&nbsp;value);&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;value;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_7_7341099" name="code" class="java" style="display: none;"> /**
     * Variant of set() to establish initialValue. Used instead
     * of set() in case user has overridden the set() method.
     *
     * @return the initial value
     */
    private T setInitialValue() {
        T value = initialValue();
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
        return value;
    }</pre><br>
　　获取和当前线程绑定的值时，ThreadLocalMap对象是以this指向的ThreadLocal对象为键进行查找的，这当然和前面set()方法的代码是相呼应的。<br>
<br>
<br>
　　进一步地，我们可以创建不同的ThreadLocal实例来实现多个变量在不同线程间的访问隔离，为什么可以这么做？因为不同的ThreadLocal对象作为不同键，当然也可以在线程的ThreadLocalMap对象中设置不同的值了。通过ThreadLocal对象，在多线程中共享一个值和多个值的区别，就像你在一个HashMap对象中存储一个键值对和多个键值对一样，仅此而已。<br>
<p></p>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
<br>
</p>
<h2><a name="t3"></a>小结</h2>
<p style="margin-top:0px; margin-bottom:0px; padding-top:0px; padding-bottom:0px; font-family:Arial; font-size:14px; line-height:26px">
　　ThreadLocal是解决线程安全问题一个很好的思路，它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下，ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单，更方便，且结果程序拥有更高的并发性。</p>
<div style="top:3168px">
<p>ConnectionManager.java</p>
<p></p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 7518px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_9" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_9" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=9&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.test;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.Connection;&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">import</span><span>&nbsp;java.sql.DriverManager;&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">import</span><span>&nbsp;java.sql.SQLException;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConnectionManager&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;ThreadLocal&lt;Connection&gt;&nbsp;connectionHolder&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ThreadLocal&lt;Connection&gt;()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="annotation">@Override</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">protected</span><span>&nbsp;Connection&nbsp;initialValue()&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection&nbsp;conn&nbsp;=&nbsp;<span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"jdbc:mysql://localhost:3306/test"</span><span>,&nbsp;</span><span class="string">"username"</span><span>,&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"password"</span><span>);&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">catch</span><span>&nbsp;(SQLException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;conn;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;Connection&nbsp;getConnection()&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;connectionHolder.get();&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setConnection(Connection&nbsp;conn)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;connectionHolder.set(conn);&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20140422_9_3421316" name="code" class="java" style="display: none;">package com.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionManager {

	private static ThreadLocal&lt;Connection&gt; connectionHolder = new ThreadLocal&lt;Connection&gt;() {
		@Override
		protected Connection initialValue() {
			Connection conn = null;
			try {
				conn = DriverManager.getConnection(
						"jdbc:mysql://localhost:3306/test", "username",
						"password");
			} catch (SQLException e) {
				e.printStackTrace();
			}
			return conn;
		}
	};

	public static Connection getConnection() {
		return connectionHolder.get();
	}

	public static void setConnection(Connection conn) {
		connectionHolder.set(conn);
	}
}</pre><br>
<p></p>
<h2><a name="t4"></a>后记</h2>
<p>　　看到网友评论的很激烈，甚至关于ThreadLocalMap不是ThreadLocal里面的，而是Thread里面的这种评论都出现了，于是有了这个后记，下面先把jdk源码贴上，源码最有说服力了。</p>
<p></p>
<div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a><span class="tracking-ad" data-mod="popu_167"><a href="https://code.csdn.net/snippets/306406" target="_blank" title="在CODE上查看代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/CODE_ico.png" width="12" height="12" alt="在CODE上查看代码片" style="position:relative;top:1px;left:2px;"></a></span><span class="tracking-ad" data-mod="popu_170"><a href="https://code.csdn.net/snippets/306406/fork" target="_blank" title="派生到我的代码片" style="text-indent:0;"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ico_fork.svg" width="12" height="12" alt="派生到我的代码片" style="position:relative;top:2px;left:2px;"></a></span><div style="position: absolute; left: 407px; top: 8255px; width: 22px; height: 12px; z-index: 99;"><embed id="ZeroClipboardMovie_10" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="22" height="12" name="ZeroClipboardMovie_10" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=10&amp;width=22&amp;height=12" wmode="transparent"></div></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;ThreadLocalMap&nbsp;is&nbsp;a&nbsp;customized&nbsp;hash&nbsp;map&nbsp;suitable&nbsp;only&nbsp;for</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;maintaining&nbsp;thread&nbsp;local&nbsp;values.&nbsp;No&nbsp;operations&nbsp;are&nbsp;exported</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;outside&nbsp;of&nbsp;the&nbsp;ThreadLocal&nbsp;class.&nbsp;The&nbsp;class&nbsp;is&nbsp;package&nbsp;private&nbsp;to</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;allow&nbsp;declaration&nbsp;of&nbsp;fields&nbsp;in&nbsp;class&nbsp;Thread.&nbsp;&nbsp;To&nbsp;help&nbsp;deal&nbsp;with</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;very&nbsp;large&nbsp;and&nbsp;long-lived&nbsp;usages,&nbsp;the&nbsp;hash&nbsp;table&nbsp;entries&nbsp;use</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;WeakReferences&nbsp;for&nbsp;keys.&nbsp;However,&nbsp;since&nbsp;reference&nbsp;queues&nbsp;are&nbsp;not</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;used,&nbsp;stale&nbsp;entries&nbsp;are&nbsp;guaranteed&nbsp;to&nbsp;be&nbsp;removed&nbsp;only&nbsp;when</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;table&nbsp;starts&nbsp;running&nbsp;out&nbsp;of&nbsp;space.</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">static</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ThreadLocalMap&nbsp;{...}&nbsp;&nbsp;</span></span></li></ol></div><pre code_snippet_id="306406" snippet_file_name="blog_20160113_10_1939309" name="code" class="java" style="display: none;">/**
     * ThreadLocalMap is a customized hash map suitable only for
     * maintaining thread local values. No operations are exported
     * outside of the ThreadLocal class. The class is package private to
     * allow declaration of fields in class Thread.  To help deal with
     * very large and long-lived usages, the hash table entries use
     * WeakReferences for keys. However, since reference queues are not
     * used, stale entries are guaranteed to be removed only when
     * the table starts running out of space.
     */
    static class ThreadLocalMap {...}</pre><br>
　　源码就是以上，这源码自然是在ThreadLocal里面的，有截图为证。
<p><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/20160113120623209" alt=""></p>
<p><br>
</p>
<p>　　本文是自己在学习ThreadLocal的时候，一时兴起，深入看了源码，思考了此类的作用、使用范围，进而联想到对传统的synchronize共享变量线程安全的问题进行比较，而总结的博文，总结一句话就是一个是锁机制进行时间换空间，一个是存储拷贝进行空间换时间。</p>
<p><br>
</p>
<p>(全文完)</p>
<p><br>
</p>
<p><br>
</p>
<p><br>
</p>
<p><br>
</p>
<p><br>
</p>
</div>
   
</div>




<!-- Baidu Button BEGIN -->




<div class="bdsharebuttonbox tracking-ad bdshare-button-style0-16" style="float: right;" data-mod="popu_172" data-bd-bind="1454132689226">
<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="bds_more" data-cmd="more" style="background-position:0 0 !important; background-image: url(http://bdimg.share.baidu.com/static/api/img/share/icons_0_16.png?v=d754dcc0.png) !important" target="_blank"></a>
<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间" style="background-position:0 -52px !important" target="_blank"></a>
<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博" style="background-position:0 -104px !important" target="_blank"></a>
<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博" style="background-position:0 -260px !important" target="_blank"></a>
<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="bds_renren" data-cmd="renren" title="分享到人人网" style="background-position:0 -208px !important" target="_blank"></a>
<a href="http://blog.csdn.net/lufeng20/article/details/24314381#" class="bds_weixin" data-cmd="weixin" title="分享到微信" style="background-position:0 -1612px !important" target="_blank"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "1", "bdMiniList": false, "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
<!-- Baidu Button END -->

   <link rel="stylesheet" href="http://static.blog.csdn.net/css/blog_detail.css">

    
<!--172.16.140.11-->

<!-- Baidu Button BEGIN -->
<script type="text/javascript" id="bdshare_js" data="type=tools&amp;uid=1536434" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/bds_s_v2.js"></script>

<script type="text/javascript">
    document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script>
<!-- Baidu Button END -->

 

        <div id="digg" articleid="24314381">
            <dl id="btnDigg" class="digg digg_disable">
               
                 <dt>顶</dt>
                <dd>31</dd>
            </dl>
            <dl id="btnBury" class="digg digg_disable">
              
                  <dt>踩</dt>
                <dd>5</dd>
            </dl>
        </div>

   <ul class="article_next_prev">
                <li class="prev_article"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_shangyipian&#39;]);location.href=&#39;/lufeng20/article/details/18554571&#39;;">上一篇</span><a href="http://blog.csdn.net/lufeng20/article/details/18554571" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_shangyipian&#39;])">【C++】linux下CMake生成动态链接库，g++包含生成动态链接库</a></li>
                <li class="next_article"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_xiayipian&#39;]);location.href=&#39;/lufeng20/article/details/44623387&#39;;">下一篇</span><a href="http://blog.csdn.net/lufeng20/article/details/44623387" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_xiayipian&#39;])">explise rcp application export导出exe问题解决</a></li>
    </ul>

    <div style="clear:both; height:10px;"></div>


        <div class="similar_article" style="">
                <h4>我的同类文章</h4>
                <div class="similar_c" style="margin:20px 0px 0px 0px">
                    <div class="similar_c_t">
                                <label class="similar_cur">
                                    <span style="cursor:pointer" onclick="GetCategoryArticles(&#39;952595&#39;,&#39;lufeng20&#39;,&#39;foot&#39;,&#39;24314381&#39;);">J2EE &amp; SSH<em>（23）</em></span>
                                </label>
                                <label class="">
                                    <span style="cursor:pointer" onclick="GetCategoryArticles(&#39;952594&#39;,&#39;lufeng20&#39;,&#39;foot&#39;,&#39;24314381&#39;);">java<em>（36）</em></span>
                                </label>
                    </div>
                   
                    <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                        <a href="http://blog.csdn.net/" style="display:none" target="_blank">http://blog.csdn.net</a>
                        <ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/18276557" id="foot_aritcle_18276557undefined11642179824411869" target="_blank" title="【protocol buffers】java解析protoBuf custom option自定义扩展文件具体方法">【protocol buffers】java解析protoBuf custom option自定义扩展文件具体方法</a><span>2014-01-14</span><label><i>阅读</i><b>3629</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7790156" id="foot_aritcle_7790156undefined08498125476762652" target="_blank" title="Freemarker 内置函数 数字、字符串、日期格式化用法介绍">Freemarker 内置函数 数字、字符串、日期格式化用法介绍</a><span>2012-07-26</span><label><i>阅读</i><b>20935</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7598564" id="foot_aritcle_7598564undefined9996290621347725" target="_blank" title="SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component">SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component</a><span>2012-05-24</span><label><i>阅读</i><b>12545</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7594632" id="foot_aritcle_7594632undefined15328597417101264" target="_blank" title="JSTL标签库介绍及EL表达式语言介绍">JSTL标签库介绍及EL表达式语言介绍</a><span>2012-05-23</span><label><i>阅读</i><b>752</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7333294" id="foot_aritcle_7333294undefined38028756668791175" target="_blank" title="Spring学习之使用关闭钩子销毁bean">Spring学习之使用关闭钩子销毁bean</a><span>2012-03-08</span><label><i>阅读</i><b>3762</b></label></li> </ul>

                        <ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/8643599" id="foot_aritcle_8643599undefined24208966363221407" target="_blank" title="反射获取对象成员的字段值，getFields()和getDeclaredFields()用法区别">反射获取对象成员的字段值，getFields()和getDeclaredFields()用法区别</a><span>2013-03-06</span><label><i>阅读</i><b>9276</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7598801" id="foot_aritcle_7598801undefined07078360882587731" target="_blank" title="SpringMVC 基于注解的Controller @RequestMapping @RequestParam..">SpringMVC 基于注解的Controller @RequestMapping @RequestParam..</a><span>2012-05-24</span><label><i>阅读</i><b>67178</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7594711" id="foot_aritcle_7594711undefined8112289430573583" target="_blank" title="shiro 授权介绍">shiro 授权介绍</a><span>2012-05-23</span><label><i>阅读</i><b>6571</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/lufeng20/article/details/7336348" id="foot_aritcle_7336348undefined1753460420295596" target="_blank" title="Hibernate学习之缓存">Hibernate学习之缓存</a><span>2012-03-09</span><label><i>阅读</i><b>688</b></label></li> </ul>
                    <a href="http://blog.csdn.net/lufeng20/article/category/952595" class="MoreArticle">更多文章</a></div>
                </div>
            </div>    
    <script type="text/javascript">
        $(function () {
            GetCategoryArticles('952595', 'lufeng20','foot','24314381');
        });
    </script>
      
</div>
<div id="suggest">

    <dl class="blog-associat-tag">
        <dt>主题推荐</dt>
        <dd>
                <a href="http://www.csdn.net/tag/java" target="_blank" class="blog-tage-red">java</a> 
                <a href="http://www.csdn.net/tag/jdk" target="_blank" class="blog-tage-red">jdk</a> 
                <a href="http://www.csdn.net/tag/%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F" target="_blank" class="blog-tage-red">局部变量</a> 
                <a href="http://www.csdn.net/tag/%E5%A4%9A%E7%BA%BF%E7%A8%8B" target="_blank" class="blog-tage-red">多线程</a> 
                <a href="http://www.csdn.net/tag/%E5%BC%80%E5%8F%91%E4%BA%BA%E5%91%98" target="_blank" class="blog-tage-red">开发人员</a> 
                <a href="http://www.csdn.net/tag/%E5%AF%B9%E8%B1%A1" target="_blank" class="blog-tage-red">对象</a> 
                <a href="http://www.csdn.net/tag/%E5%B9%B6%E5%8F%91" target="_blank" class="blog-tage-red">并发</a> 
                <a href="http://www.csdn.net/tag/%E7%BA%BF%E7%A8%8B" target="_blank" class="blog-tage-red">线程</a> 
                <a href="http://www.csdn.net/tag/class" target="_blank" class="blog-tage-red">class</a> 
        </dd>        
    </dl> 
    <span style="display:none" id="tags">java,jdk,局部变量,多线程,开发人员,对象,并发,线程,class</span>

</div>
         <script language="javascript" type="text/javascript">     
             $(function(){
                 $.get("/lufeng20/svc/GetSuggestContent/24314381",function(data){
                     $("#suggest").html(data);
                 });     
             });             
         </script>  


<style>
.blog-ass-articl dd {
color: #369;
width: 99%; /*修改行*/
float: left;
overflow: hidden;
font: normal normal 12px/23px "SimSun";
height: 23px;
margin: 0;
padding: 0 0 0 10px;
margin-right: 30px;
background: url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;
}
</style>

<dl class="blog-ass-articl" id="res-relatived"> 
     <dt><span>猜你在找</span></dt>    


   


    <div id="adCollege" style="width: 42%;float: left;"> 
        <script src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/job_reco.js" type="text/javascript"></script> 
        <script type="text/javascript">
            csdn.position.showEdu({
                sourceType: "blog",
                searchType: "detail",
                searchKey: "24314381",
                username: "",
                recordcount: "5",
                containerId: "adCollege" //容器DIV的id。 
            });
        </script> 
    <div class="tracking-ad" data-mod="popu_84"><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/1810" title="深入浅出Spring" strategy="v4:content" target="_blank">深入浅出Spring</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/731" title="Java基础核心技术：面向对象编程(day05-day07)" strategy="v4:content" target="_blank">Java基础核心技术：面向对象编程(day05-day07)</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/791" title="JavaWeb程序设计" strategy="v4:content" target="_blank">JavaWeb程序设计</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/1536" title="SpringMVC Spring Hibernate框架整合视频" strategy="v4:content" target="_blank">SpringMVC Spring Hibernate框架整合视频</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/1403" title="全网首套_Spring&amp;SpringMVC;&amp;JPA;&amp;SpringData; 整合案例视频" strategy="v4:content" target="_blank">全网首套_Spring&amp;SpringMVC;&amp;JPA;&amp;SpringData; 整合案例视频</a></dd></div></div>  

    
     <div id="res" data-mod="popu_36" class="tracking-ad" style="width: 42%; float: left; margin-right: 30px; display: block;"><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/F7ANTY/article/details/47278089" title="Java线程面试题 Top 50" strategy="SearchAlgorithm" target="_blank">Java线程面试题 Top 50</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/leicool_518/article/details/42293357" title="Java线程面试题 Top 50" strategy="SearchAlgorithm" target="_blank">Java线程面试题 Top 50</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/u010530506/article/details/38842905" title="Java线程面试题 Top 50" strategy="SearchAlgorithm" target="_blank">Java线程面试题 Top 50</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/super2007/article/details/38724865" title="Java线程面试题Top50" strategy="SearchAlgorithm" target="_blank">Java线程面试题Top50</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/jxiang112/article/details/38745107" title="Java线程面试题Top50" strategy="SearchAlgorithm" target="_blank">Java线程面试题Top50</a></dd></div>
   
</dl>



<script type="text/javascript">
    $(function () {
        setTimeout(function () {
            var searchtitletags = '彻底理解ThreadLocal' + ',' + $("#tags").html();
            searchService({
                index: 'blog',
                query: searchtitletags,
                from: 5,
                size: 5,
                appendTo: '#res',
                url: 'recommend',
                his: 2,
                client: "blog_cf_enhance",
                tmpl: '<dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="#{ url }" title="#{ title }" strategy="#{ strategy }">#{ title }</a></dd>'
            });
        }, 500);
    });    

 </script>   

    <div id="ad_cen">        
<!--AdForward Begin:-->
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/s(1)" charset="gbk"></script><script type="text/javascript">
/*博客频道内容页下方Banner728*90，创建于2014-7-3*/
var cpro_id = "u1607657";
</script>
<script src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/c.js" type="text/javascript"></script><div id="BAIDU_UNION__wrapper_u1607657_0"><iframe id="iframeu1607657_0" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/acom.html" width="728" height="90" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" style="border:0; vertical-align:bottom;margin:0;" allowtransparency="true"></iframe></div>
<!--AdForward End-->    </div>  

<div class="comment_class">
    <div id="comment_title" class="panel_head">
        <span class="see_comment">查看评论</span><a name="comments"></a></div>
    <div id="comment_list"><dl class="comment_item comment_topic" id="comment_item_5844440"><dt class="comment_head" floor="29">29楼 <span class="user"><a class="username" href="http://blog.csdn.net/xj2419174554" target="_blank">晓风残月xj</a> <span class="ptime">2016-01-16 22:03发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5844440" username="xj2419174554"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/xj2419174554" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_xj2419174554.jpg" width="40" height="40"></a></dd><dd class="comment_body">楼主，您好。看源码认为：“ThreadLocal使得各线程能够保持各自独立的一个对象，并不是通过ThreadLocal.set()来实现的，而是通过每个线程中的new 对象 的操作来创建的对象，每个线程创建一个，不是什么对象的拷贝或副本。”</dd></dl><dl class="comment_item comment_topic" id="comment_item_5843398"><dt class="comment_head" floor="28">28楼 <span class="user"><a class="username" href="http://blog.csdn.net/u012691505" target="_blank">Siny_YN</a> <span class="ptime">2016-01-15 17:47发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5843398" username="u012691505"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u012691505" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u012691505.jpg" width="40" height="40"></a></dd><dd class="comment_body">可能还很菜，感觉楼主的理解够用，楼下评论中的有的还不理解。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5833653"><dt class="comment_head" floor="27">27楼 <span class="user"><a class="username" href="http://blog.csdn.net/liuchaoxuan" target="_blank">liuchaouxan</a> <span class="ptime">2016-01-07 11:52发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5833653" username="liuchaoxuan"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/liuchaoxuan" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_liuchaoxuan.jpg" width="40" height="40"></a></dd><dd class="comment_body">幸亏先看了评论~~~~~</dd></dl><dl class="comment_item comment_topic" id="comment_item_5765478"><dt class="comment_head" floor="26">26楼 <span class="user"><a class="username" href="http://blog.csdn.net/lhc2207221755" target="_blank">水田如雅</a> <span class="ptime">2016-01-04 19:38发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5765478" username="lhc2207221755"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lhc2207221755" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lhc2207221755.jpg" width="40" height="40"></a></dd><dd class="comment_body">楼下评论好混战~</dd></dl><dl class="comment_item comment_topic" id="comment_item_5754451"><dt class="comment_head" floor="25">25楼 <span class="user"><a class="username" href="http://blog.csdn.net/u012661091" target="_blank">raynforu</a> <span class="ptime">2015-12-30 11:06发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5754451" username="u012661091"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u012661091" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u012661091.jpg" width="40" height="40"></a></dd><dd class="comment_body">博主的jdk是哪个版本的？JDK1.8中使用的不再是threadlocalMap了，而是直接存储在线程中的哈希数组localValues。</dd><dl class="comment_item comment_reply" id="comment_item_5754523"><dt class="comment_head" floor="25">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2015-12-30 11:22发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5754523" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u012661091：没记错的话，应该是1.7版本。</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5733228"><dt class="comment_head" floor="24">24楼 <span class="user"><a class="username" href="http://blog.csdn.net/lszzzz" target="_blank">lszzzz</a> <span class="ptime">2015-12-21 22:25发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5733228" username="lszzzz"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lszzzz" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lszzzz.jpg" width="40" height="40"></a></dd><dd class="comment_body">写的很清楚，支持！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5633029"><dt class="comment_head" floor="23">23楼 <span class="user"><a class="username" href="http://blog.csdn.net/lhwbake" target="_blank">lhwbake</a> <span class="ptime">2015-11-23 15:02发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5633029" username="lhwbake"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lhwbake" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lhwbake.jpg" width="40" height="40"></a></dd><dd class="comment_body">赞</dd></dl><dl class="comment_item comment_topic" id="comment_item_5615129"><dt class="comment_head" floor="22">22楼 <span class="user"><a class="username" href="http://blog.csdn.net/u012772007" target="_blank">大嘴蛙</a> <span class="ptime">2015-11-15 20:24发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5615129" username="u012772007"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u012772007" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u012772007.jpg" width="40" height="40"></a></dd><dd class="comment_body">ThreadLocal是如何做到为每一个线程维护变量的副本的呢？其实实现的思路很简单：在ThreadLocal类中有一个Map，用于存储每一个线程的变量副本，Map中元素的键为线程对象，而值对应线程的变量副本。<br>这句对ThreadLocal实现的理解完全错误，希望网友不要被误导，实际上ThreadLocal类中并没有Map，而是在每个Thread中有各自对应的ThreadLocalMap，每个ThreadLocalMap都是以ThreadLocal实例为键存储变量值的，需要存储多个变量值的话就需要多个ThreadLocal实例。</dd><dl class="comment_item comment_reply" id="comment_item_5840306"><dt class="comment_head" floor="22">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2016-01-13 11:54发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5840306" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u012772007：这位网友，你错了，你去看jdk源码，会发现ThreadLocalMap是ThreadLocal的静态内部类，只要看了源码，这是毫无疑问的，你看完源码再来评论好么？</dd></dl><dl class="comment_item comment_reply" id="comment_item_5725325"><dt class="comment_head" floor="22">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Mark_LQ" target="_blank">SunnyMarkLiu</a> <span class="ptime">2015-12-16 17:37发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5725325" username="Mark_LQ"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Mark_LQ" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_mark_lq.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u012772007：说的没错！但ThreadLocal中的ThreadLocalMap其实就是一个map，或者说原理就是一个map，JDK中的解释是一个定制化的hash map：ThreadLocalMap is a customized hash map suitable only for maintaining thread local values. ThreadLocalMap中包含一个Entry(ThreadLocal&lt;?&gt; k, Object v)以及Entry[]数组，这两个也就实现了map的功能。但是key为ThreadLocal。</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5528785"><dt class="comment_head" floor="21">21楼 <span class="user"><a class="username" href="http://blog.csdn.net/eccel" target="_blank">eccel</a> <span class="ptime">2015-10-23 15:58发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5528785" username="eccel"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/eccel" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_eccel.jpg" width="40" height="40"></a></dd><dd class="comment_body">要彻底理解ThreadLocal-看源码自己最清楚了，楼主理解确实有误差。跟同步毛关系没有。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5459811"><dt class="comment_head" floor="20">20楼 <span class="user"><a class="username" href="http://blog.csdn.net/mhsfw007" target="_blank">mhsfw007</a> <span class="ptime">2015-09-29 16:58发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5459811" username="mhsfw007"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/mhsfw007" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_mhsfw007.jpg" width="40" height="40"></a></dd><dd class="comment_body">花好长时间看完正文才看到评论，说楼主坑人，我都快哭了，但我想说的是，按照楼主的理解去使用ThreadLocal并无什么不妥，至于太高端的用法就不说了，普通程序一般不会因对原理的理解有偏差而掉进“坑”里吧。对楼主和指出楼主错误的大牛们表示敬意。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5407349"><dt class="comment_head" floor="19">19楼 <span class="user"><a class="username" href="http://blog.csdn.net/u010032372" target="_blank">-琥珀川-</a> <span class="ptime">2015-09-11 18:07发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5407349" username="u010032372"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u010032372" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u010032372.jpg" width="40" height="40"></a></dd><dd class="comment_body">今天面试出了关于threadlocal的题</dd></dl><dl class="comment_item comment_topic" id="comment_item_5390305"><dt class="comment_head" floor="18">18楼 <span class="user"><a class="username" href="http://blog.csdn.net/chang0507" target="_blank">chang0507</a> <span class="ptime">2015-09-04 22:15发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5390305" username="chang0507"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/chang0507" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_chang0507.jpg" width="40" height="40"></a></dd><dd class="comment_body">ThreadLocal和线程同步机制相比有什么优势呢？ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。<br><br>看到上面这句话就直奔评论来了</dd></dl><dl class="comment_item comment_topic" id="comment_item_5389105"><dt class="comment_head" floor="17">17楼 <span class="user"><a class="username" href="http://blog.csdn.net/WinWill2012" target="_blank">winwill2012</a> <span class="ptime">2015-09-04 01:27发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5389105" username="WinWill2012"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/WinWill2012" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_winwill2012.jpg" width="40" height="40"></a></dd><dd class="comment_body">楼主理解得好像有点点问题，建议大家去看看这篇文章吧<br>http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83]%E8%A7%A3%E5%AF%86ThreadLocal/<br>比较深入详细地介绍了ThreadLocal的实现原理，并讨论了ThreadLocal到底会不会引发内存泄露。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5305103"><dt class="comment_head" floor="16">16楼 <span class="user"><a class="username" href="http://blog.csdn.net/qingxili" target="_blank">qingxili</a> <span class="ptime">2015-08-14 11:42发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5305103" username="qingxili"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qingxili" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_qingxili.jpg" width="40" height="40"></a></dd><dd class="comment_body">ThreadLocal 不是用于解决共享变量的问题的，不是为了协调线程同步而存在，而是为了方便每个线程处理自己的状态而引入的一个机制，理解这点对正确使用ThreadLocal至关重要。</dd><dl class="comment_item comment_reply" id="comment_item_5493415"><dt class="comment_head" floor="16">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lirui50123" target="_blank">萨满哥</a> <span class="ptime">2015-10-09 16:12发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5493415" username="lirui50123"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lirui50123" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lirui50123.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复qingxili：同意层主</dd></dl><dl class="comment_item comment_reply" id="comment_item_5389109"><dt class="comment_head" floor="16">Re: <span class="user"><a class="username" href="http://blog.csdn.net/WinWill2012" target="_blank">winwill2012</a> <span class="ptime">2015-09-04 01:30发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5389109" username="WinWill2012"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/WinWill2012" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_winwill2012.jpg" width="40" height="40"></a></dd><dd class="comment_body">完全同意，楼主理解有点点问题，建议大家去看这篇文章<br>http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83]%E8%A7%A3%E5%AF%86ThreadLocal/<br>比较详细深入地介绍了ThreadLocal的实现原理，并探讨了ThreadLocal是否真的会引起内存泄露。</dd></dl><dl class="comment_item comment_reply" id="comment_item_5389107"><dt class="comment_head" floor="16">Re: <span class="user"><a class="username" href="http://blog.csdn.net/WinWill2012" target="_blank">winwill2012</a> <span class="ptime">2015-09-04 01:29发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5389107" username="WinWill2012"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/WinWill2012" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_winwill2012.jpg" width="40" height="40"></a></dd><dd class="comment_body">完全同意，楼主理解有点点问题，建议大家去看这篇文章<br>http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83]%E8%A7%A3%E5%AF%86ThreadLocal/<br>比较详细深入地介绍了ThreadLocal的实现原理，并探讨了ThreadLocal是否真的会引起内存泄露。</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5276527"><dt class="comment_head" floor="15">15楼 <span class="user"><a class="username" href="http://blog.csdn.net/u010014658" target="_blank">asdf780</a> <span class="ptime">2015-08-04 14:20发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5276527" username="u010014658"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u010014658" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u010014658.jpg" width="40" height="40"></a></dd><dd class="comment_body">楼主在坑人，楼主写的完全是错的，大家可以自己看源码，就全都明白了，ThreadLocal根本就不是解决共享变量的问题，而是每一个线程会隔离开来存储数据，所以线程之间根本就不会共享变量。所以大家一定要注意ThreadLocal是用来隔离线程存储数据的。但是楼主的奉献精神还是值得表扬的。</dd><dl class="comment_item comment_reply" id="comment_item_5837966"><dt class="comment_head" floor="15">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lndhuyang" target="_blank">lndhuyang</a> <span class="ptime">2016-01-11 15:34发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5837966" username="lndhuyang"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lndhuyang" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lndhuyang.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u010014658：仔细看--------概括起来说，对于多线程资源共享的问题，同步机制采用了“以时间换空间”的方式，而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量，让不同的线程排队访问，而后者为每一个线程都提供了一份变量，因此可以同时访问而互不影响。-----------<br><br>楼主说的“以空间换时间”和你说的"每一个线程会隔离开来存储数据"是一个意思。</dd></dl><dl class="comment_item comment_reply" id="comment_item_5412969"><dt class="comment_head" floor="15">Re: <span class="user"><a class="username" href="http://blog.csdn.net/wuquangui_2014_job" target="_blank">wuquangui_2014_job</a> <span class="ptime">2015-09-14 23:27发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5412969" username="wuquangui_2014_job"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/wuquangui_2014_job" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_wuquangui_2014_job.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u010014658：</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5276525"><dt class="comment_head" floor="14">14楼 <span class="user"><a class="username" href="http://blog.csdn.net/u010014658" target="_blank">asdf780</a> <span class="ptime">2015-08-04 14:19发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5276525" username="u010014658"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u010014658" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u010014658.jpg" width="40" height="40"></a></dd><dd class="comment_body">楼主在坑人，楼主写的完全是错的，大家可以自己看源码，就全都明白了，ThreadLocal根本就不是解决共享变量的问题，而是每一个线程会隔离开来存储数据，所以线程之间根本就不会共享变量。所以大家一定要注意ThreadLocal是用来隔离线程存储数据的。但是楼主的奉献精神还是值得表扬的。</dd><dl class="comment_item comment_reply" id="comment_item_5837960"><dt class="comment_head" floor="14">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lndhuyang" target="_blank">lndhuyang</a> <span class="ptime">2016-01-11 15:32发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5837960" username="lndhuyang"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lndhuyang" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lndhuyang.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u010014658：你仔细看了楼主的文章吗？ 对这句话你是怎么理解的呢？-----概括起来说，对于多线程资源共享的问题，同步机制采用了“以时间换空间”的方式，而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量，让不同的线程排队访问，而后者为每一个线程都提供了一份变量，因此可以同时访问而互不影响。----------- 这和你说的“每一个线程会隔离开来存储数据”完全是同一个意思。只不过楼主的说法是“以空间换时间”。本质没有任何区别。至少本人看了觉得大有帮助，说楼主坑人太离谱了。</dd><dl class="comment_item comment_reply" id="comment_item_5840277"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2016-01-13 11:40发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5840277" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复lndhuyang：嗯，你说的挺对的，其实就是“用空间换时间”，线程自己存储一份拷贝，所以不会有线程安全问题。</dd></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_5238559"><dt class="comment_head" floor="13">13楼 <span class="user"><a class="username" href="http://blog.csdn.net/u012967289" target="_blank">易碎的泪</a> <span class="ptime">2015-07-29 15:38发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5238559" username="u012967289"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u012967289" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u012967289.jpg" width="40" height="40"></a></dd><dd class="comment_body">lz，我还是没有明白，每个程序该遍了自己的副本，其它的程序不知道，有什么用呀，是不是没有实现数据的共享。</dd><dl class="comment_item comment_reply" id="comment_item_5840465"><dt class="comment_head" floor="13">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2016-01-13 14:37发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5840465" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复u012967289：不同线程访问数据的时候，是多线程数据共享的问题，本文的解法主要是用空间换时间。</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5226029"><dt class="comment_head" floor="12">12楼 <span class="user"><a class="username" href="http://blog.csdn.net/tyzhsj" target="_blank">tyzhsj</a> <span class="ptime">2015-07-25 15:42发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5226029" username="tyzhsj"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/tyzhsj" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_tyzhsj.jpg" width="40" height="40"></a></dd><dd class="comment_body">写的很好的一篇关于ThreadLocal的博文，感谢博主</dd></dl><dl class="comment_item comment_topic" id="comment_item_5194289"><dt class="comment_head" floor="11">11楼 <span class="user"><a class="username" href="http://blog.csdn.net/mar_ljh" target="_blank">疯狂的赣江</a> <span class="ptime">2015-07-09 17:31发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5194289" username="mar_ljh"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/mar_ljh" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_mar_ljh.jpg" width="40" height="40"></a></dd><dd class="comment_body">public void remove()将当前线程局部变量的值删除，目的是为了减少内存的占用，该方法是JDK 5.0新增的方法。需要指出的是，当线程结束后，对应该线程的局部变量将自动被垃圾回收，所以显式调用该方法清除线程的局部变量并不是必须的操作，但它可以加快内存回收的速度。<br><br>在我们大部分的使用都是将ThreadLocal作为一个静态的变量来使用的。因此，楼主这句话很容易让人误解啊，，，切记，不要偷懒，最好用完记得要remove！！！否则，怎么死都不知道！</dd></dl><dl class="comment_item comment_topic" id="comment_item_4916951"><dt class="comment_head" floor="10">10楼 <span class="user"><a class="username" href="http://blog.csdn.net/oBuTianBuNi" target="_blank">mini宝儿</a> <span class="ptime">2015-04-06 05:24发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4916951" username="oBuTianBuNi"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/oBuTianBuNi" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_obutianbuni.jpg" width="40" height="40"></a></dd><dd class="comment_body">我来看看，面试问了，不会，认真看过之后，在看到5楼的纠正，有点乱啊。+_+</dd><dl class="comment_item comment_reply" id="comment_item_4982215"><dt class="comment_head" floor="10">Re: <span class="user"><a class="username" href="http://blog.csdn.net/mc46790090" target="_blank">mc46790090</a> <span class="ptime">2015-04-28 19:11发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4982215" username="mc46790090"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/mc46790090" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_mc46790090.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复oBuTianBuNi：建议看http://www.iteye.com/topic/103804<br>5楼说的很对，threadlocal压根就不是为了解决变量共享的问题的，只是为了避免同一线程中对象参数传递而提出的。</dd><dl class="comment_item comment_reply" id="comment_item_5060057"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/liuyeliufeng" target="_blank">走在菜鸟的路上</a> <span class="ptime">2015-05-19 09:56发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5060057" username="liuyeliufeng"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/liuyeliufeng" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_liuyeliufeng.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复mc46790090：其实题主只是有些概念有些让人误解，但是他的理解没有问题，ThreadLocal提出就是为了解决共享变量的线程同步问题的，对象拷贝只是实现的效果，其内部是通过创建线程内部变量实现的，源码中写道：Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the &lt;tt&gt;ThreadLocal&lt;/tt&gt; instance is accessible;</dd><dl class="comment_item comment_reply" id="comment_item_5080321"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/mc46790090" target="_blank">mc46790090</a> <span class="ptime">2015-05-27 14:16发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5080321" username="mc46790090"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/mc46790090" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_mc46790090.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复liuyeliufeng：@mini宝儿，不好意思，链接是http://www.iteye.com/topic/103804。5楼说的很对，你可以看下。<br>至于这位兄弟，我想说“同步个卵啊，你自己都翻译出来了‘这个类提供线程内部变量，这些变量和正常变量不同，因为每个线程都有自己并独立初始化的变量拷贝。ThreadLocal实例通常是私有静态变量，并通常和线程的状态有关。’”<br>每个线程中都有一个独立的threadlocal变量拷贝，你告诉我咋跨线程同步？能不能看看源码啊。。。少年<br>为博主的分享精神点赞，但是希望博主以后能尽量理解准确之后再发文，不然容易将新手带歪的....如果理解之后好歹把博文改一下哈</dd><dl class="comment_item comment_reply" id="comment_item_5184885" style="margin-left:0;"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/u014655269" target="_blank">IMTOP</a> <span class="ptime">2015-07-04 15:30发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5184885" username="u014655269"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u014655269" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_u014655269.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复mc46790090：ThreadLocal实例通常是私有静态变量，并通常和线程的状态有关，其实关键就在这句话，可能ThreadLocal的初衷并不是为了解决对象的共享问题，但是在某些情况下确实适用。因为和线程的状态有关，所以每个线程都生成一个副本，那就可以解决一个对象在并发下的共享问题。个人理解，如果说的不对请指出。</dd></dl></dl></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_4916949"><dt class="comment_head" floor="9">9楼 <span class="user"><a class="username" href="http://blog.csdn.net/oBuTianBuNi" target="_blank">mini宝儿</a> <span class="ptime">2015-04-06 05:22发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4916949" username="oBuTianBuNi"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/oBuTianBuNi" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_obutianbuni.jpg" width="40" height="40"></a></dd><dd class="comment_body">我来看看，面试问了，不会，不过认真看完之后，被5楼的纠正弄的有点乱+_+</dd></dl><dl class="comment_item comment_topic" id="comment_item_4793533"><dt class="comment_head" floor="8">8楼 <span class="user"><a class="username" href="http://blog.csdn.net/chenleiking" target="_blank">chenleiking</a> <span class="ptime">2015-02-11 16:23发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4793533" username="chenleiking"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/chenleiking" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_chenleiking.jpg" width="40" height="40"></a></dd><dd class="comment_body">结合大家的看法和自己的研究，我举个例子，看看在这种情况下是不是使用ThreadLocal比较贴切：<br>1、我有一个类，在实例化的时候需要消耗大量的系统资源的和时间，但是在单例模式下又会存在线程安全的问题；<br>2、尽管在单例模式下会有线程安全的问题，我依然使用单例实现，只是将geInstance方法略作修改，在“geInstance”方法中加入ThreadLocal，每次都从ThreadLocal中get我的对象实例；<br>3、这样既不用重复繁重的创建对象实例，然后因为ThreadLocal的线程隔离，也不用考虑线程安全问题；<br>以上是我的理解，不知道是否正确，或存在不足之处，希望大家赐教！</dd></dl><dl class="comment_item comment_topic" id="comment_item_4739959"><dt class="comment_head" floor="7">7楼 <span class="user"><a class="username" href="http://blog.csdn.net/yinwt111" target="_blank">yinwt111</a> <span class="ptime">2015-01-26 15:53发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4739959" username="yinwt111"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yinwt111" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_yinwt111.jpg" width="40" height="40"></a></dd><dd class="comment_body">5楼分析的很正确</dd><dl class="comment_item comment_reply" id="comment_item_5134249"><dt class="comment_head" floor="7">Re: <span class="user"><a class="username" href="http://blog.csdn.net/zcqshine" target="_blank">zcqshine</a> <span class="ptime">2015-06-10 09:22发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5134249" username="zcqshine"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zcqshine" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_zcqshine.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复yinwt111：这样用貌似是木有问题的, 相当于是在单例中为每个线程拷贝了一个副本, 而副本之间互不影响.</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_4725001"><dt class="comment_head" floor="6">6楼 <span class="user"><a class="username" href="http://blog.csdn.net/xurui8691413" target="_blank">xurui8691413</a> <span class="ptime">2015-01-20 22:06发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4725001" username="xurui8691413"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/xurui8691413" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_xurui8691413.jpg" width="40" height="40"></a></dd><dd class="comment_body">5楼说的很对，楼主并没有理解threadlocal的真正含义。ThreadLocal是线程范围内的资源共享，并不能在多线程共享资源的情况下使用，因为他会为每个线程创建独立的资源，且不可与其他线程共享</dd></dl><dl class="comment_item comment_topic" id="comment_item_4445997"><dt class="comment_head" floor="5">5楼 <span class="user"><a class="username" href="http://blog.csdn.net/zhuwhzyjsxy" target="_blank">zhuwhzyjsxy</a> <span class="ptime">2014-10-28 14:03发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4445997" username="zhuwhzyjsxy"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zhuwhzyjsxy" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_zhuwhzyjsxy.jpg" width="40" height="40"></a></dd><dd class="comment_body">首先为楼主的分享精神表示敬佩。但是楼主的这个帖子很容易误人子弟~<br>1.ThreadLocal不是用来解决共享对象的多线程访问问题的，一定要扯上关系，结果就是这样，大家都看不懂你在说什么。<br>2.ThreadLocal的实现并不是楼主说的在其内部提供了一个Map，用Thread作为key；用Thread作为key就会存在共享变量的同步与并发问题，会对ThreadLocal进行加锁，楼主源码已经很清晰的说明了实现机制，我就不分析了。<br>3.ThreadLocal并不是为线程保存了对象的副本，ThreadLocal是为每个线程隔离了一个类的实例，这个实例的作用于仅限于线程内部。楼主的“序列号”的例子不够贴切，因为对原始类型的赋值操作都是对这个值的拷贝。楼主可能要说，那我这是Integer类型，怎么说？那我要说的是，原始类型的封装类型在做运算的时候，先解封，再运算，然后把结果重新封装成新的对象，显然，这依然是一个副本，所以，不能说是为线程保存了对象的副本，楼主选择例子一定要慎重。。<br>4.如果真的涉及到多线程共享的时候，ThreadLocal是解决不了这个问题的，既然作为共享变量，ThreadLocal并不是为线程提供共享变量的副本，而仅仅是为线程隔离对象，那我要问了，为线程隔离共享变量的意义是什么？毫无意义，本来就是共享的变量，隔离的目的是让其他线程无法访问，这已经违背了共享变量的目的了。。对共享变量的读写是需要同步机制实现的。。。<br>后面我来简单解释一下ThreadLocal的作用~<br>我们从这个类的名字就能了解到类的作用，ThreadLocal可以分解为Thread，和Local，前者就不多说了，后者的意思是局部，整个类名可以理解为：线程局部对象。程序是运行在线程中的，所以，在整个运行过程中，在任何地方都可以获得这个线程的局部对象，你从线程内部取出的局部对象难道会变成其他线程的对象么？显然不会啊。</dd><dl class="comment_item comment_reply" id="comment_item_5455953"><dt class="comment_head" floor="5">Re: <span class="user"><a class="username" href="http://blog.csdn.net/qq_23359777" target="_blank">qq_23359777</a> <span class="ptime">2015-09-29 00:45发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5455953" username="qq_23359777"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qq_23359777" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_qq_23359777.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复zhuwhzyjsxy：层主，这最后一段真的是发人深醒啊！</dd></dl><dl class="comment_item comment_reply" id="comment_item_4859957"><dt class="comment_head" floor="5">Re: <span class="user"><a class="username" href="http://blog.csdn.net/z282762779" target="_blank">z282762779</a> <span class="ptime">2015-03-18 20:33发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4859957" username="z282762779"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/z282762779" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_z282762779.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复zhuwhzyjsxy：5楼我想问一下 你4,5点是支持是副本，还是支持是隔离对象?我没看错的话楼主是觉得是个副本。</dd><dl class="comment_item comment_reply" id="comment_item_5060099"><dt class="comment_head" floor="2">Re: <span class="user"><a class="username" href="http://blog.csdn.net/liuyeliufeng" target="_blank">走在菜鸟的路上</a> <span class="ptime">2015-05-19 10:09发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5060099" username="liuyeliufeng"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/liuyeliufeng" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_liuyeliufeng.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复z282762779：This class provides thread-local variables.  These variables differ from their normal counterparts in that each thread that accesses one (via its &lt;tt&gt;get&lt;/tt&gt; or &lt;tt&gt;set&lt;/tt&gt; method) has its own, independently initialized copy of the variable.  &lt;tt&gt;ThreadLocal&lt;/tt&gt; instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).<br>大概意思翻译一下：<br>这个类提供线程内部变量，这些变量和正常变量不同，因为每个线程都有自己并独立初始化的变量拷贝。ThreadLocal实例通常是私有静态变量，并通常和线程的状态有关。</dd></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_4120571"><dt class="comment_head" floor="4">4楼 <span class="user"><a class="username" href="http://blog.csdn.net/memoryisking" target="_blank">memoryisking</a> <span class="ptime">2014-08-01 13:13发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="4120571" username="memoryisking"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/memoryisking" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_memoryisking.jpg" width="40" height="40"></a></dd><dd class="comment_body">关于更多ThreadLocal的内容可以去看这里：<a href="http://www.strutshome.com/index.php/archives/501" target="_blank">ThreadLocal的源码分析</a></dd></dl><dl class="comment_item comment_topic" id="comment_item_3993169"><dt class="comment_head" floor="3">3楼 <span class="user"><a class="username" href="http://blog.csdn.net/hejingyuan6" target="_blank">何静媛</a> <span class="ptime">2014-06-26 21:45发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3993169" username="hejingyuan6"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hejingyuan6" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_hejingyuan6.jpg" width="40" height="40"></a></dd><dd class="comment_body">很棒的threadLocal总结，学习了</dd></dl><dl class="comment_item comment_topic" id="comment_item_3957961"><dt class="comment_head" floor="2">2楼 <span class="user"><a class="username" href="http://blog.csdn.net/Sup_Heaven" target="_blank">Sup_Heaven</a> <span class="ptime">2014-06-16 09:16发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3957961" username="Sup_Heaven"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Sup_Heaven" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_sup_heaven.jpg" width="40" height="40"></a></dd><dd class="comment_body">可能太菜，还是不太明白。<br>据我所知Servlet是单例的，但是是支持多线程的，也就是说多个线程会使用同一个Servlet。虽然这样，线程A使用该Servlet的doservice()是在线程A中，线程B使用该Servlet的doservice()是在线程B中，那么doservice()中的DAO层必然也在同一个线程中。<br>小弟菜鸟，求LZ耐心解释，谢谢。</dd><dl class="comment_item comment_reply" id="comment_item_3958071"><dt class="comment_head" floor="2">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2014-06-16 09:55发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3958071" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Sup_Heaven：你说的线程A和线程B来说，那么他们并发访问的情况下，doservice()中的DAO层必然在同一个线程中么？可能就不在一个线程了，if (connThreadLocal.get() == null) 这里A判断是Null，所以他进去实例化了一个Connection，B这个时候也访问正好A还没实例化完毕，B看到的也是Null，B也去实例化一个Connection，那么就有两个Connection，这就是不同的Connection了。。。</dd><dl class="comment_item comment_reply" id="comment_item_3958879"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Sup_Heaven" target="_blank">Sup_Heaven</a> <span class="ptime">2014-06-16 14:57发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3958879" username="Sup_Heaven"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Sup_Heaven" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_sup_heaven.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复lufeng20：怎么感觉越来越乱了，我说说我整体的理解。<br>假设有请求RA和请求RB，他们都会去访问ServletA（，简称SA），那么这时肯定是在两个线程（假设线程A,B）中同时跑SA。<br>在SA中有dopost方法，该方法执行某个Service的doservice（）方法；<br>doservice(){<br>DAO d1=new DAOA()；<br>d1.dodaoa();<br>DAO d2=new DAOB()；<br>d2.dodaob();<br>}<br>那么这样下来的必定每个请求对应一个线程，所以各自的doservice（）方法在各自的线程中执行，所以仔线程A中当DAOA会先新建Connection，DAOB也用DAOA新建的Connection，同样在线程B中也是这么个情况。<br>所以我觉得这句话下面不对，不知道是我哪一步理解错了，号纠结啊。<br>“当然，这个例子本身很粗糙，将Connection的ThreadLocal直接放在DAO只能做到本DAO的多个方法共享Connection时不发生线程安全问题，但无法和其它DAO共用同一个Connection，要做到同一事务多DAO共享同一Connection，必须在一个共同的外部类使用ThreadLocal保存Connection。“</dd><dl class="comment_item comment_reply" id="comment_item_3958897"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2014-06-16 15:02发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3958897" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Sup_Heaven：DAO里面获取collection是共享的 public static Connection getConnection()，“但无法和其它DAO共用同一个Connection”这句说说的线程安全问题就是这个，结合if (connThreadLocal.get() == null) 这里就可能发生线程安全</dd><dl class="comment_item comment_reply" id="comment_item_3959183" style="margin-left:0;"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Sup_Heaven" target="_blank">Sup_Heaven</a> <span class="ptime">2014-06-16 16:13发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3959183" username="Sup_Heaven"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Sup_Heaven" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_sup_heaven.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复lufeng20：好吧，关键是下，下面的Connection conn = getConnection(); <br>if (connThreadLocal.get() == null) {  <br>            Connection conn = getConnection();  <br>            connThreadLocal.set(conn);  <br>            return conn;  <br>        }<br>不知道你的getConnection(); 是怎么获得的，如果一个线程中先DAOA，发现该线程没有Connection便从连接池中拿一个并保存在当前线程中，接着同一个线程中的DAOB执行，发现有当前线程已经有Connection，就直接用了，还是同一个啊。<br>不知道是你和我谈的不是一样的东西，还是我真的想错了？</dd><dl class="comment_item comment_reply" id="comment_item_3959347" style="margin-left:0;"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2014-06-16 16:56发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3959347" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Sup_Heaven：getConnection()这里的实现当然是最基本底层的的数据库连接来实现。。少年，麻烦你认真看我的回复好么。。“if (connThreadLocal.get() == null) 这里A判断是Null，所以他进去实例化了一个Connection，B这个时候也访问正好A还没实例化完毕，B看到的也是Null，B也去实例化一个Connection，那么就有两个Connection，这就是不同的Connection了”  这里哪儿有连接池？？都是自己实现的放在Connection conn = getConnection();  <br>            connThreadLocal.set(conn);  这里set之后放在threadLocal里面的好么？如果有不止AB,还有CDEFG等同时并发访问，看到的都是Null那么他们都会自己去getConnection，这样就会产生多个了！！！</dd><dl class="comment_item comment_reply" id="comment_item_3959441" style="margin-left:0;"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Sup_Heaven" target="_blank">Sup_Heaven</a> <span class="ptime">2014-06-16 17:27发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3959441" username="Sup_Heaven"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Sup_Heaven" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_sup_heaven.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复lufeng20：你的回复我当然仔细看了，总觉得我和你说的不是同一个东西，这次放上代码，哈哈。<br>public class ConnectionManager {<br>	private static ThreadLocal&lt;Connection&gt; connectionHolder = new ThreadLocal&lt;Connection&gt;() {<br>		protected Connection initialValue() {<br>			Connection conn = null;<br>			try {<br>				conn = DriverManager.getConnection(<br>					url,username,password);<br>			} catch (SQLException e) {<br>				e.printStackTrace();<br>			}<br>			return conn;<br>		}<br>	};<br>	public static Connection getConnection() {<br>		return connectionHolder.get();<br>	}<br>	public static void setConnection(Connection conn) {<br>		connectionHolder.set(conn);<br>	}<br>}<br>public class TestService {<br>	public void doservice() throws SQLException{<br>		Statement stat1 = ConnectionManager.getConnection().createStatement();<br>		stat1.execute("sql1");<br>		Statement stat2 = ConnectionManager.getConnection().createStatement();<br>		stat2.execute("sql2");<br>	}<br>}<br>我的意思就是一个线程访问doservice() 方法，里面两次获取（ConnectionManager.getConnection()）的connection必然是同一个connection，而不同线程必然获得不同的connection，难道不是这样吗？</dd><dl class="comment_item comment_reply" id="comment_item_3959465" style="margin-left:0;"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2014-06-16 17:34发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3959465" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Sup_Heaven：你附的代码这个是改进之后的，当然就没问题了，public static Connection getConnection() {  <br>        // ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection，  <br>        // 并将其保存到线程本地变量中。  <br>        if (connThreadLocal.get() == null) {  <br>            Connection conn = getConnection();  <br>            connThreadLocal.set(conn);  <br>            return conn;  <br>        } else {  <br>            return connThreadLocal.get();// ③直接返回线程本地变量  <br>        }  <br>    }  <br>这个是改进之前的，这里就存在线程安全的问题</dd><dl class="comment_item comment_reply" id="comment_item_3959537" style="margin-left:0;"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Sup_Heaven" target="_blank">Sup_Heaven</a> <span class="ptime">2014-06-16 17:56发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3959537" username="Sup_Heaven"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Sup_Heaven" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_sup_heaven.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复lufeng20：就算改造之前的，我觉得下面的一个线程在执行doservice() 方法时两次getConnection拿到的也是同一个Connection，因为在该线程内doservice() 方法是被线性执行的。当然每个线程拿到的Connection是不一样的。<br>public void doservice() {<br>Statement stat1 = ConnectionManager.getConnection().createStatement();<br>stat1.execute("sql1");<br>Statement stat2 = ConnectionManager.getConnection().createStatement();<br>stat2.execute("sql2");<br>}</dd></dl></dl></dl></dl></dl></dl></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_3953517"><dt class="comment_head" floor="1">1楼 <span class="user"><a class="username" href="http://blog.csdn.net/Sup_Heaven" target="_blank">Sup_Heaven</a> <span class="ptime">2014-06-13 17:46发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3953517" username="Sup_Heaven"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Sup_Heaven" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_sup_heaven.jpg" width="40" height="40"></a></dd><dd class="comment_body">“当然，这个例子本身很粗糙，将Connection的ThreadLocal直接放在DAO只能做到本DAO的多个方法共享Connection时不发生线程安全问题，但无法和其它DAO共用同一个Connection，要做到同一事务多DAO共享同一Connection，必须在一个共同的外部类使用ThreadLocal保存Connection。“<br>如果从Action到Service都是一个线程，那么在某个service中有<br>doservice(){<br>DAO d1=new DAOA()；<br>d1.dodaoa();<br>DAO d2=new DAOB()；<br>d2.dodaob();<br>}<br>那此时难道他们不再同一个线程中，获取的是不同的Connection，我不太明白，求LZ解释？</dd><dl class="comment_item comment_reply" id="comment_item_5741341"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/zljjava" target="_blank">zljjava</a> <span class="ptime">2015-12-24 18:24发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5741341" username="zljjava"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zljjava" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_zljjava.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Sup_Heaven： 你的代码说明就是一个线程，但不一定是一个Connection。得跟据 <br>private static ThreadLocal&lt;Connection&gt; connThreadLocal = new ThreadLocal&lt;Connection&gt;(); <br>在DAO 还是在DAOA/DAOB里。</dd></dl><dl class="comment_item comment_reply" id="comment_item_3953579"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/lufeng20" target="_blank">枫之逆</a> <span class="ptime">2014-06-13 18:12发表</span>  <a href="http://blog.csdn.net/lufeng20/article/details/24314381#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="3953579" username="lufeng20"> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/lufeng20/article/details/24314381#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lufeng20" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/3_lufeng20.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Sup_Heaven：在一个doservice()里面是同一个，因为他们是同一个线程，但是不同的HTTP请求，对servlet来说都是一个线程，当并发请求的时候，不同线程用doservice()方法来响应，那么就可能有线程安全的问题，获取的可能就是不同的Connection。我说明白了吧？</dd></dl></dl><div class="clear"></div></div>
    <div id="comment_bar" style="display: none;">
    </div>
    <div id="comment_form"><div class="guest_link">您还没有登录,请<a href="javascript:void(0);" onclick="javascript:loginbox();">[登录]</a>或<a href="http://passport.csdn.net/account/register?from=http%3A%2F%2Fblog.csdn.net%2Flufeng20%2Farticle%2Fdetails%2F24314381">[注册]</a></div></div>
    <div class="announce">
        * 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场<a name="reply"></a><a name="quote"></a></div>
</div>

<script type="text/javascript">
    var fileName = '24314381';
    var commentscount = 58;
    var islock = false
</script>
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/comment.js"></script>
    <div id="ad_bot">
    </div>
<div id="report_dialog">
</div>

<div id="d-top" style="bottom:60px;">
        <a id="quick-reply" class="btn btn-top q-reply" title="快速回复" style="display:none;">
            <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/blog-icon-reply.png" alt="快速回复">
        </a>    

    <a id="d-top-a" class="btn btn-top backtop" style="display: none;" title="返回顶部" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_huidaodingbu&#39;])">         
         <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/top.png" alt="TOP">
    </a>
</div>
<script type="text/javascript">
    $(function ()
    {
        $("#ad_frm_0").height("90px");
        
        setTimeout(function(){
            $("#ad_frm_2").height("200px");
        },1000);    
    });
  
</script>
<style type="text/css">
    .tag_list
    {
        background: none repeat scroll 0 0 #FFFFFF;
        border: 1px solid #D7CBC1;
        color: #000000;
        font-size: 12px;
        line-height: 20px;
        list-style: none outside none;
        margin: 10px 2% 0 1%;
        padding: 1px;
    }
    .tag_list h5
    {
        background: none repeat scroll 0 0 #E0DBD3;
        color: #47381C;
        font-size: 12px;
        height: 24px;
        line-height: 24px;
        padding: 0 5px;
        margin: 0;
    }
    .tag_list h5 a
    {
        color: #47381C;
    }
    .classify
    {
        margin: 10px 0;
        padding: 4px 12px 8px;
    }
    .classify a
    {
        margin-right: 20px;
        white-space: nowrap;
    }
</style>


<div class="tag_list" style="">

    <h5>
        <a href="http://www.csdn.net/tag/" target="_blank">核心技术类目</a></h5>
    <div class="classify">
<a title="全部主题" href="http://www.csdn.net/tag" target="_blank" onclick="LogClickCount(this,336);">全部主题</a>
<a title="Hadoop" href="http://g.csdn.net/5272865" target="_blank" onclick="LogClickCount(this,336);">Hadoop</a>
<a title="AWS" href="http://g.csdn.net/5272866" target="_blank" onclick="LogClickCount(this,336);">AWS</a>
<a title="移动游戏" href="http://g.csdn.net/5272870" target="_blank" onclick="LogClickCount(this,336);">移动游戏</a>
<a title="Java" href="http://g.csdn.net/5272871" target="_blank" onclick="LogClickCount(this,336);">Java</a>
<a title="Android" href="http://g.csdn.net/5272872" target="_blank" onclick="LogClickCount(this,336);">Android</a>
<a title="iOS" href="http://g.csdn.net/5272873" target="_blank" onclick="LogClickCount(this,336);">iOS</a>
<a title="Swift" href="http://g.csdn.net/5272868" target="_blank" onclick="LogClickCount(this,336);">Swift</a>
<a title="智能硬件" href="http://g.csdn.net/5272869" target="_blank" onclick="LogClickCount(this,336);">智能硬件</a>
<a title="Docker" href="http://g.csdn.net/5272867" target="_blank" onclick="LogClickCount(this,336);">Docker</a>
<a title="OpenStack" href="http://g.csdn.net/5272925" target="_blank" onclick="LogClickCount(this,336);">OpenStack</a>
<a title="VPN" href="http://www.csdn.net/tag/vpn" target="_blank" onclick="LogClickCount(this,336);">VPN</a>
<a title="Spark" href="http://g.csdn.net/5272924" target="_blank" onclick="LogClickCount(this,336);">Spark</a>
<a title="ERP" href="http://www.csdn.net/tag/erp" target="_blank" onclick="LogClickCount(this,336);">ERP</a>
<a title="IE10" href="http://www.csdn.net/tag/ie10" target="_blank" onclick="LogClickCount(this,336);">IE10</a>
<a title="Eclipse" href="http://www.csdn.net/tag/eclipse" target="_blank" onclick="LogClickCount(this,336);">Eclipse</a>
<a title="CRM" href="http://www.csdn.net/tag/crm" target="_blank" onclick="LogClickCount(this,336);">CRM</a>
<a title="JavaScript" href="http://www.csdn.net/tag/javascript" target="_blank" onclick="LogClickCount(this,336);">JavaScript</a>
<a title="数据库" href="http://www.csdn.net/tag/%E6%95%B0%E6%8D%AE%E5%BA%93" target="_blank" onclick="LogClickCount(this,336);">数据库</a>
<a title="Ubuntu" href="http://www.csdn.net/tag/ubuntu" target="_blank" onclick="LogClickCount(this,336);">Ubuntu</a>
<a title="NFC" href="http://www.csdn.net/tag/nfc" target="_blank" onclick="LogClickCount(this,336);">NFC</a>
<a title="WAP" href="http://www.csdn.net/tag/wap" target="_blank" onclick="LogClickCount(this,336);">WAP</a>
<a title="jQuery" href="http://www.csdn.net/tag/jquery" target="_blank" onclick="LogClickCount(this,336);">jQuery</a>
<a title="BI" href="http://www.csdn.net/tag/bi" target="_blank" onclick="LogClickCount(this,336);">BI</a>
<a title="HTML5" href="http://www.csdn.net/tag/html5" target="_blank" onclick="LogClickCount(this,336);">HTML5</a>
<a title="Spring" href="http://www.csdn.net/tag/spring" target="_blank" onclick="LogClickCount(this,336);">Spring</a>
<a title="Apache" href="http://www.csdn.net/tag/apache" target="_blank" onclick="LogClickCount(this,336);">Apache</a>
<a title=".NET" href="http://www.csdn.net/tag/.net" target="_blank" onclick="LogClickCount(this,336);">.NET</a>
<a title="API" href="http://www.csdn.net/tag/api" target="_blank" onclick="LogClickCount(this,336);">API</a>
<a title="HTML" href="http://www.csdn.net/tag/html" target="_blank" onclick="LogClickCount(this,336);">HTML</a>
<a title="SDK" href="http://www.csdn.net/tag/sdk" target="_blank" onclick="LogClickCount(this,336);">SDK</a>
<a title="IIS" href="http://www.csdn.net/tag/iis" target="_blank" onclick="LogClickCount(this,336);">IIS</a>
<a title="Fedora" href="http://www.csdn.net/tag/fedora" target="_blank" onclick="LogClickCount(this,336);">Fedora</a>
<a title="XML" href="http://www.csdn.net/tag/xml" target="_blank" onclick="LogClickCount(this,336);">XML</a>
<a title="LBS" href="http://www.csdn.net/tag/lbs" target="_blank" onclick="LogClickCount(this,336);">LBS</a>
<a title="Unity" href="http://www.csdn.net/tag/unity" target="_blank" onclick="LogClickCount(this,336);">Unity</a>
<a title="Splashtop" href="http://www.csdn.net/tag/splashtop" target="_blank" onclick="LogClickCount(this,336);">Splashtop</a>
<a title="UML" href="http://www.csdn.net/tag/uml" target="_blank" onclick="LogClickCount(this,336);">UML</a>
<a title="components" href="http://www.csdn.net/tag/components" target="_blank" onclick="LogClickCount(this,336);">components</a>
<a title="Windows Mobile" href="http://www.csdn.net/tag/windowsmobile" target="_blank" onclick="LogClickCount(this,336);">Windows Mobile</a>
<a title="Rails" href="http://www.csdn.net/tag/rails" target="_blank" onclick="LogClickCount(this,336);">Rails</a>
<a title="QEMU" href="http://www.csdn.net/tag/qemu" target="_blank" onclick="LogClickCount(this,336);">QEMU</a>
<a title="KDE" href="http://www.csdn.net/tag/kde" target="_blank" onclick="LogClickCount(this,336);">KDE</a>
<a title="Cassandra" href="http://www.csdn.net/tag/cassandra" target="_blank" onclick="LogClickCount(this,336);">Cassandra</a>
<a title="CloudStack" href="http://www.csdn.net/tag/cloudstack" target="_blank" onclick="LogClickCount(this,336);">CloudStack</a>
<a title="FTC" href="http://www.csdn.net/tag/ftc" target="_blank" onclick="LogClickCount(this,336);">FTC</a>
<a title="coremail" href="http://www.csdn.net/tag/coremail" target="_blank" onclick="LogClickCount(this,336);">coremail</a>
<a title="OPhone " href="http://www.csdn.net/tag/ophone" target="_blank" onclick="LogClickCount(this,336);">OPhone </a>
<a title="CouchBase" href="http://www.csdn.net/tag/couchbase" target="_blank" onclick="LogClickCount(this,336);">CouchBase</a>
<a title="云计算" href="http://www.csdn.net/tag/%E4%BA%91%E8%AE%A1%E7%AE%97" target="_blank" onclick="LogClickCount(this,336);">云计算</a>
<a title="iOS6" href="http://www.csdn.net/tag/iOS6" target="_blank" onclick="LogClickCount(this,336);">iOS6</a>
<a title="Rackspace " href="http://www.csdn.net/tag/rackspace" target="_blank" onclick="LogClickCount(this,336);">Rackspace </a>
<a title="Web App" href="http://www.csdn.net/tag/webapp" target="_blank" onclick="LogClickCount(this,336);">Web App</a>
<a title="SpringSide" href="http://www.csdn.net/tag/springside" target="_blank" onclick="LogClickCount(this,336);">SpringSide</a>
<a title="Maemo" href="http://www.csdn.net/tag/maemo" target="_blank" onclick="LogClickCount(this,336);">Maemo</a>
<a title="Compuware" href="http://www.csdn.net/tag/compuware" target="_blank" onclick="LogClickCount(this,336);">Compuware</a>
<a title="大数据" href="http://www.csdn.net/tag/%E5%A4%A7%E6%95%B0%E6%8D%AE" target="_blank" onclick="LogClickCount(this,336);">大数据</a>
<a title="aptech" href="http://www.csdn.net/tag/aptech" target="_blank" onclick="LogClickCount(this,336);">aptech</a>
<a title="Perl" href="http://www.csdn.net/tag/perl" target="_blank" onclick="LogClickCount(this,336);">Perl</a>
<a title="Tornado" href="http://www.csdn.net/tag/tornado" target="_blank" onclick="LogClickCount(this,336);">Tornado</a>
<a title="Ruby" href="http://www.csdn.net/tag/ruby" target="_blank" onclick="LogClickCount(this,336);">Ruby</a>
<a title="Hibernate" href="http://www.csdn.net/hibernate" target="_blank" onclick="LogClickCount(this,336);">Hibernate</a>
<a title="ThinkPHP" href="http://www.csdn.net/tag/thinkphp" target="_blank" onclick="LogClickCount(this,336);">ThinkPHP</a>
<a title="HBase" href="http://www.csdn.net/tag/hbase" target="_blank" onclick="LogClickCount(this,336);">HBase</a>
<a title="Pure" href="http://www.csdn.net/tag/pure" target="_blank" onclick="LogClickCount(this,336);">Pure</a>
<a title="Solr" href="http://www.csdn.net/tag/solr" target="_blank" onclick="LogClickCount(this,336);">Solr</a>
<a title="Angular" href="http://www.csdn.net/tag/angular" target="_blank" onclick="LogClickCount(this,336);">Angular</a>
<a title="Cloud Foundry" href="http://www.csdn.net/tag/cloudfoundry" target="_blank" onclick="LogClickCount(this,336);">Cloud Foundry</a>
<a title="Redis" href="http://www.csdn.net/tag/redis" target="_blank" onclick="LogClickCount(this,336);">Redis</a>
<a title="Scala" href="http://www.csdn.net/tag/scala" target="_blank" onclick="LogClickCount(this,336);">Scala</a>
<a title="Django" href="http://www.csdn.net/tag/django" target="_blank" onclick="LogClickCount(this,336);">Django</a>
<a title="Bootstrap" href="http://www.csdn.net/tag/bootstrap" target="_blank" onclick="LogClickCount(this,336);">Bootstrap</a>
    </div>

</div>
  <script language="javascript" type="text/javascript">     
      $(function(){
              setTimeout(function(){
                  $.get("/lufeng20/svc/GetTagContent",function(data){
                      $(".tag_list").html(data).show();
                  });     
              });
          },500);                       
 </script> 


<div id="pop_win" style="display:none ;position: absolute; z-index: 10000; border: 1px solid rgb(220, 220, 220); top: 222.5px; left: 630px; opacity: 1; background: none 0px 0px repeat scroll rgb(255, 255, 255);">
    
</div>
<div id="popup_mask"></div>
<style>
    #popup_mask
    {
        position: absolute;
        width: 100%;
        height: 100%;
        background: #000;
        z-index: 9999;
        left: 0px;
        top: 0px;
        opacity: 0.3;
        filter: alpha(opacity=30);
        display: none;
    }

</style>




<script type="text/javascript">
    $(function(){
        setTimeout(function(){
            $(".comment_body:contains('回复')").each(function(index,item){
                var u=$(this).text().split('：')[0].toString().replace("回复","")
                var thisComment=$(this);
                if(u)
                {
                    $.getJSON("https://passport.csdn.net/get/nick?callback=?", {users: u}, function(a) {
                        if(a!=null&&a.data!=null&&a.data.length>0)
                        {
                            nick=a.data[0].n; 
                            if(u!=nick)
                            {
                                thisComment.text(thisComment.text().replace(u,nick));  
                            }
                        }       
                    });  
                }
            });
        },200);  
        
        setTimeout(function(){
            $("a img[src='http://js.tongji.linezing.com/stats.gif']").parent().css({"position":"absolute","left":"50%"});
        },300);
    });

    function loginbox(){
        var $logpop=$("#pop_win");
        $logpop.html('<iframe src="https://passport.csdn.net/account/loginbox?service=http://static.blog.csdn.net/callback.htm" frameborder="0" height="600" width="400" scrolling="no"></iframe>');

        $('#popup_mask').css({
            opacity: 0.5,
            width: $( document ).width() + 'px',
            height:  $( document ).height() + 'px'
        });
        $('#popup_mask').css("display","block");
 
        $logpop.css( {
            top: ($( window ).height() - $logpop.height())/ 2  + $( window 
       ).scrollTop() + 'px',
            left:($( window ).width() - $logpop.width())/ 2
        } );
 
        setTimeout( function () {
            $logpop.show();
            $logpop.css( {
                opacity: 1
            } );
        }, 200 );
 
        $('#popup_mask').unbind("click");
        $('#popup_mask').bind("click", function(){
            $('#popup_mask').hide();
            var $clopop = $("#pop_win");
            $("#common_ask_div_sc").css("display","none");
            $clopop.css( {
                opacity: 0
            } );
            setTimeout( function () {
                $clopop.hide();
            }, 350 );
            return false;
        });
    }    

</script>
                        <div class="clear">
                        </div>
                    </div>                   
                
            </div>
                   
           <div id="side">
    <div class="side">


<div id="custom_column_21587708" class="panel">
<ul class="panel_head"><span>公告</span></ul>
<ul class="panel_body">

<span style="display:block">转载请注明出处<br>
<a target="_blank" href="http://blog.csdn.net/lufeng20">http://blog.csdn.net/lufeng20</a>
</span>

</ul>
</div><div id="panel_Profile" class="panel">
<ul class="panel_head"><span>个人资料</span></ul>
<ul class="panel_body profile">
<div id="blog_userface">
    <a href="http://my.csdn.net/lufeng20" target="_blank">
    <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/1_lufeng20.jpg" title="访问我的空间" style="max-width:90%">
    </a>
    <br>
    <span><a href="http://my.csdn.net/lufeng20" class="user_name" target="_blank">枫之逆</a></span>
</div>
<div class="interact">

    <a href="javascript:void(0);" class="attent" id="span_add_follow" title="[加关注]"></a>

 <a href="javascript:void(0);" class="letter" title="[发私信]" onclick="window.open(&#39;http://msg.csdn.net/letters/model?receiver=lufeng20&#39;,&#39;_blank&#39;,&#39;height=350,width=700&#39;);_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_sixin&#39;])"></a>  
</div>
<div id="blog_medal">
                <div id="bms_box">
               </div>
</div>
<ul id="blog_rank">
    <li>访问：<span>474688次</span></li>
    <li>积分：<span>4972</span> </li>    
    <li>等级： <span style="position:relative;display:inline-block;z-index:1">
            <img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/blog5.png" alt="" style="vertical-align: middle;" id="leveImg">
            <div id="smallTittle" style=" position: absolute;  left: -24px;  top: 25px;  text-align: center;  width: 101px;  height: 32px;  background-color: #fff;  line-height: 32px;  border: 2px #DDDDDD solid;  box-shadow: 0px 2px 2px rgba (0,0,0,0.1);  display: none;   z-index: 999;">
            <div style="left: 42%;  top: -8px;  position: absolute;  width: 0;  height: 0;  border-left: 10px solid transparent;  border-right: 10px solid transparent;  border-bottom: 8px solid #EAEAEA;"></div>
            积分：4972 </div>
        </span>  </li>
    <li>排名：<span>第3100名</span></li>
</ul>
<ul id="blog_statistics">
    <li>原创：<span>89篇</span></li>
    <li>转载：<span>18篇</span></li>
    <li>译文：<span>1篇</span></li>
    <li>评论：<span>246条</span></li>
</ul>
</ul>
</div>


<div id="panel_Category" class="panel">
<ul class="panel_head"><span>文章分类</span></ul>
<ul class="panel_body">    
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/952595" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">J2EE &amp; SSH</a><span>(24)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/952594" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">java</a><span>(37)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1122776" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">算法</a><span>(13)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1085480" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">设计模式</a><span>(6)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1108724" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">ubuntu</a><span>(5)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1090031" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">数据库</a><span>(4)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1100287" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">计算机组成</a><span>(2)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1086789" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">UML</a><span>(1)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1091589" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">PHP</a><span>(2)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1108613" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">sublime</a><span>(4)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1154738" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">生活感悟</a><span>(8)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1177725" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">javascript</a><span>(2)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1152892" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">mybatis</a><span>(4)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1160415" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">eclipse</a><span>(4)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1160459" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">jquery</a><span>(2)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1354621" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">protobuf</a><span>(4)</span>
                </li>
                 <li>
                    <a href="http://blog.csdn.net/lufeng20/article/category/1867071" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_wenzhangfenlei&#39;]); ">C++</a><span>(1)</span>
                </li>
</ul>
</div>

<div id="custom_column_22427055" class="panel">
<ul class="panel_head"><span>友情链家-志同道合</span></ul>
<ul class="panel_body">

<span style="display:block"><a target="_blank" href="http://1.wp4dzx.sinaapp.com/" style="color:blue">二拯救世界</a></span><span style="display:block"><a target="_blank" href="http://blog.csdn.net/fbd2011"> 小米饭团</a></span><span style="display:block">
<a target="_blank" href="http://coolshell.cn/" style="color:blue">酷壳</a></span><span style="display:block">
<a target="_blank" href="http://m.young.blog.163.com/" style="color:blue">m.young 杨卫民blog</a></span>
<span style="display:block"><a target="_blank" href="http://blog.csdn.net/djfengqiang?viewmode=list" style="color:blue">天涯星空</a></span>

</ul>
</div><div class="panel" id="panel_Search">
    <ul class="panel_head"><span>文章搜索</span></ul>
    <ul class="panel_body">
        <form id="frmSearch" action="http://so.csdn.net/search" class="form_search" target="_blank">
        <span><input id="inputSearch" type="text" class="blogsearch" title="请输入关键字"></span>
        <input id="btnSubmit" type="button" value="搜索" title="search in blog">
        <input type="hidden" name="q" id="inputQ">
        <input type="hidden" name="t" value="blog">
        <a id="btnSearchBlog" target="_blank"></a>
        </form>
    </ul>
</div>

<script type="text/javascript">
    $(function () {
        $("#btnSubmit").click(function () {           
            search();
        });

        $("#frmSearch").submit(function () {
            search();
            return false;
        });

        function search()
        {
            var url = "http://so.csdn.net/so/search/s.do?q=" + encodeURIComponent($("#inputSearch").val()) + "&u=" + username + "&t=blog";
            window.location.href = url;
        }   
    });
</script><div id="panel_Archive" class="panel">
<ul class="panel_head"><span>文章存档</span></ul>
<ul class="panel_body">
<div id="archive_list"><li><a href="http://blog.csdn.net/lufeng20/article/month/2015/03">2015年03月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2014/04">2014年04月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2014/01">2014年01月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2013/10">2013年10月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2013/09">2013年09月</a><span>(3)</span></li><span class="hidelist" style="display:none;"><li><a href="http://blog.csdn.net/lufeng20/article/month/2013/04">2013年04月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2013/03">2013年03月</a><span>(5)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/10">2012年10月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/09">2012年09月</a><span>(9)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/08">2012年08月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/07">2012年07月</a><span>(6)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/06">2012年06月</a><span>(8)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/05">2012年05月</a><span>(15)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/04">2012年04月</a><span>(8)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/03">2012年03月</a><span>(27)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2012/02">2012年02月</a><span>(10)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2011/12">2011年12月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/lufeng20/article/month/2011/11">2011年11月</a><span>(2)</span></li></span><div id="archive_list_button" class="list_closed">展开</div></div>
</ul>
</div>
<div id="hotarticls" class="panel">
<ul class="panel_head">
    <span>       
阅读排行    </span>
</ul>

<ul class="panel_body itemlist">
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7598801" title="SpringMVC 基于注解的Controller @RequestMapping @RequestParam..">SpringMVC 基于注解的Controller @RequestMapping @RequestParam..</a><span>(67231)</span>
</li>
<li>
<a href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET.html" title="彻底理解ThreadLocal">彻底理解ThreadLocal</a><span>(57177)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7629555" title="Eclipse启动时fail to create Java Virtual Machine问题的解决">Eclipse启动时fail to create Java Virtual Machine问题的解决</a><span>(24956)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7790156" title="Freemarker 内置函数 数字、字符串、日期格式化用法介绍">Freemarker 内置函数 数字、字符串、日期格式化用法介绍</a><span>(20953)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7598564" title="SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component">SpringMVC 用注解Annotation驱动的IoC功能@Autowired @Component</a><span>(12563)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7641093" title="svn:is not under version control and is not part of the commit, yet its child解决办法">svn:is not under version control and is not part of the commit, yet its child解决办法</a><span>(12005)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7404369" title="解决xubuntu 11.10下使用Sublime Text 2无法输入中文的问题">解决xubuntu 11.10下使用Sublime Text 2无法输入中文的问题</a><span>(11001)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/18554571" title="【C++】linux下CMake生成动态链接库，g++包含生成动态链接库">【C++】linux下CMake生成动态链接库，g++包含生成动态链接库</a><span>(10526)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/11161507" title="File already exists: filesystem &#39;/path/file&#39;, transaction svn常见错误解决方法">File already exists: filesystem '/path/file', transaction svn常见错误解决方法</a><span>(10392)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7406577" title="sublime text2下进行ftp连接笔记">sublime text2下进行ftp连接笔记</a><span>(10286)</span>
</li>
</ul>
</div>
<div id="hotarticls2" class="panel">
<ul class="panel_head"><span>评论排行</span></ul>
<ul class="panel_body itemlist">
<li>
<a href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET.html" title="彻底理解ThreadLocal">彻底理解ThreadLocal</a><span>(58)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7598801" title="SpringMVC 基于注解的Controller @RequestMapping @RequestParam..">SpringMVC 基于注解的Controller @RequestMapping @RequestParam..</a><span>(40)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7542955" title="K-means算法的java实现，聚类分析681个三国武将">K-means算法的java实现，聚类分析681个三国武将</a><span>(28)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7406577" title="sublime text2下进行ftp连接笔记">sublime text2下进行ftp连接笔记</a><span>(12)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7629555" title="Eclipse启动时fail to create Java Virtual Machine问题的解决">Eclipse启动时fail to create Java Virtual Machine问题的解决</a><span>(11)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/8730604" title="反射+枚举+freemarker，自动生成实体类，自动建表建索引（一）之生成实体类，枚举详解">反射+枚举+freemarker，自动生成实体类，自动建表建索引（一）之生成实体类，枚举详解</a><span>(10)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/11149669" title="Eclipse设置代码高亮，设置代码样式">Eclipse设置代码高亮，设置代码样式</a><span>(9)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/8087457" title="做真正的自己，to be the truthful yourself">做真正的自己，to be the truthful yourself</a><span>(6)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7486182" title="谨纪念第一次面试，电话面试，百度一面。。">谨纪念第一次面试，电话面试，百度一面。。</a><span>(6)</span>
</li>
<li>
<a href="http://blog.csdn.net/lufeng20/article/details/7430640" title="清明。。只是扫墓。。">清明。。只是扫墓。。</a><span>(6)</span>
</li>
</ul>
</div>
<div id="homepageArticles" class="panel tracking-ad" data-mod="popu_4">
<ul class="panel_head"><span>推荐文章</span></ul>
<ul class="panel_body" id="ad_commend">
<ul>
<li><a href="http://blog.csdn.net/wingichoy/article/details/50590051" target="_blank">*一个炫字都不够？？！！！手把手带你打造3D自定义view</a></li>
<li><a href="http://blog.csdn.net/Pwiling/article/details/50573650" target="_blank">*21行python代码实现拼写检查器</a></li>
<li><a href="http://blog.csdn.net/u011225629/article/details/50492403" target="_blank">*数据库性能优化之SQL语句优化</a></li>
<li><a href="http://blog.csdn.net/bluecloudmatrix/article/details/50525225" target="_blank">*拉开大变革序幕（下）：分布式计算框架与大数据</a></li>
<li><a href="http://blog.csdn.net/luoshengyang/article/details/50527574" target="_blank">*Chromium网页URL加载过程分析</a></li>
<li><a href="http://blog.csdn.net/androidlushangderen/article/details/50571584" target="_blank">*Hadoop中止下线操作后大量剩余复制块的解决方案</a></li>

</ul></ul>
</div>


<div id="newcomments" class="panel">
<ul class="panel_head"><span>最新评论</span></ul>
<ul class="panel_body itemlist">
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/xj2419174554" class="user_name">晓风残月xj</a>:
楼主，您好。看源码认为：“ThreadLocal使得各线程能够保持各自独立的一个对象，并不是通过Th...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/u012691505" class="user_name">Siny_YN</a>:
可能还很菜，感觉楼主的理解够用，楼下评论中的有的还不理解。
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lufeng20" class="user_name">枫之逆</a>:
@u012967289:不同线程访问数据的时候，是多线程数据共享的问题，本文的解法主要是用空间换时间...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lufeng20" class="user_name">枫之逆</a>:
@u012772007:这位网友，你错了，你去看jdk源码，会发现ThreadLocalMap是Th...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lufeng20" class="user_name">枫之逆</a>:
@lndhuyang:嗯，你说的挺对的，其实就是“用空间换时间”，线程自己存储一份拷贝，所以不会有线...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lndhuyang" class="user_name">lndhuyang</a>:
@u010014658:仔细看--------概括起来说，对于多线程资源共享的问题，同步机制采用了“...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lndhuyang" class="user_name">lndhuyang</a>:
@u010014658:你仔细看了楼主的文章吗？ 对这句话你是怎么理解的呢？-----概括起来说，对...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/liuchaoxuan" class="user_name">liuchaouxan</a>:
幸亏先看了评论~~~~~
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/24314381#comments">彻底理解ThreadLocal</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lhc2207221755" class="user_name">水田如雅</a>:
楼下评论好混战~
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/lufeng20/article/details/18554571#comments">【C++】linux下CMake生成动态链接库，g++包含生成动态链接库</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/lufeng20" class="user_name">枫之逆</a>:
@zzcoffeebean:崩溃应该就是由于c++抛异常了，C++没有像java的异常处理机制，只要...
    </p>
    </li>
</ul>
</div>
    </div>
    <div class="clear">
    </div>
 </div>   
            <div class="clear">
            </div>
        </div>
        

<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/cnick.js"></script>
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/newblog.min.js"></script>


<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/showblogmedal.ashx"></script>
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/JavaScript1.js"></script><link rel="stylesheet" type="text/css" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/pub_footer_2014.css"><div class="pub_fo"><div id="pub_footerall" class="pub_footer_new"><dl><dt></dt> <dd class="foot_sub_menu"><a href="http://www.csdn.net/company/about.html" target="_blank">公司简介</a><span>|</span><a href="http://www.csdn.net/company/recruit.html" target="_blank">招贤纳士</a><span>|</span><a href="http://www.csdn.net/company/marketing.html" target="_blank">广告服务</a><span>|</span><a href="http://www.csdn.net/company/account.html" target="_blank">银行汇款帐号</a><span>|</span><a href="http://www.csdn.net/company/contact.html" target="_blank">联系方式</a><span>|</span><a href="http://www.csdn.net/company/statement.html" target="_blank">版权声明</a><span>|</span><a href="http://www.csdn.net/company/layer.html" target="_blank">法律顾问</a><span>|</span><a href="mailto:webmaster@csdn.net">问题报告</a><span>|</span><a target="_blank" href="http://www.csdn.net/friendlink.html">合作伙伴</a><span>|</span><a href="http://bbs.csdn.net/forums/Service" target="_blank">论坛反馈</a></dd><dd class="foot_contact"><a href="http://wpa.qq.com/msgrd?v=3&uin=2355263776&site=qq&menu=yes" target="_blank" class="qq">网站客服</a><a href="http://wpa.qq.com/msgrd?v=3&uin=2251809102&site=qq&menu=yes" target="_blank" class="qq">杂志客服</a><a href="http://e.weibo.com/csdnsupport/profile" target="_blank" class="weibo">微博客服</a><a href="mailto:webmaster@csdn.net" class="email" title="联系邮箱">webmaster@csdn.net</a><span class="phone" title="服务热线">400-600-2320</span><span class="interval">|</span><span>北京创新乐知信息技术有限公司 版权所有</span><span class="interval">|</span><span>江苏乐知网络技术有限公司 提供商务支持</span></dd><dd class="foot_copyright"><span>京&nbsp;ICP&nbsp;证&nbsp;09002463&nbsp;号</span><span class="interval">|</span><span>Copyright © 1999-2014, CSDN.NET, All Rights Reserved&nbsp;</span><a href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010" target="_blank"><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/gongshang_logos.gif" alt="GongshangLogo" title=""></a></dd></dl></div></div><div id="note1" class="csdn_note" style="display:none; position:absolute; z-index:9999; width:440px">  <span class="notice_top_arrow"><span class="inner"></span></span>  <div class="box"></div></div><div class="csdn_notice_tip" style="display: none; position: absolute; z-index: 9990; width: 170px;">  <iframe src="about:blank" frameborder="0" scrolling="no" style="z-index:-1;position:absolute;top:0;left:0;width:100%;height:100%;background:transparent"></iframe>  <div class="tip_text">您有<strong>0</strong>条新通知</div>  <a href="javascript:void 0" class="close2"></a></div><script id="noticeScript" type="text/javascript" btnid="header_notice_num" wrapid="note1" count="5" subcount="5" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/notify.js"></script>

    <script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/login.js"></script>
<script type="text/javascript">document.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");</script><img src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/pv.aspx" border="0" width="0" height="0">
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/counter.js"></script><script type="text/javascript" charset="UTF-8" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/msg.popup.js"></script>
<script type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ad-blog.js"></script>
<script type="text/javascript">
    $(function () {
        function __get_code_toolbar(snippet_id) {
            return $("<span class='tracking-ad' data-mod='popu_167'><a href='https://code.csdn.net/snippets/"
                    + snippet_id
                    + "' target='_blank' title='在CODE上查看代码片'  style='text-indent:0;'><img src='https://code.csdn.net/assets/CODE_ico.png' width=12 height=12 alt='在CODE上查看代码片' style='position:relative;top:1px;left:2px;'/></a></span>"
                    + "<span class='tracking-ad' data-mod='popu_170'><a href='https://code.csdn.net/snippets/"
                    + snippet_id
                    + "/fork' target='_blank' title='派生到我的代码片' style='text-indent:0;'><img src='https://code.csdn.net/assets/ico_fork.svg' width=12 height=12 alt='派生到我的代码片' style='position:relative;top:2px;left:2px;'/></a></span>");
        }
        
        $("[code_snippet_id]").each(function () {
            __s_id = $(this).attr("code_snippet_id");
            if (__s_id != null && __s_id != "" && __s_id != 0 && parseInt(__s_id) > 70020) {
                __code_tool = __get_code_toolbar(__s_id);
                $(this).prev().find(".tools").append(__code_tool);
            }
        });

        $(".bar").show();
    });
</script>




    </div><input type="hidden" id="aa_g_data_ids">
      <!--new top-->
    
    <script id="csdn-toolbar-id" btnid="header_notice_num" wrapid="note1" count="5" subcount="5" type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/toolbar.js"></script>
     <!--new top-->
   
    <link href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ask_float_block.css" type="text/css" rel="stylesheet">
    <script language="JavaScript" type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/wmd.js"></script>
    <script language="JavaScript" type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/showdown.js"></script>
    <script language="JavaScript" type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/prettify.js"></script>
    <script language="JavaScript" type="text/javascript" src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ask_float_block.js"></script>
   

   
 <div id="tag-suggest-pop">
  <div class="relative">
    <div class="close"></div>
    <div class="content"></div>
  </div>
</div><link rel="stylesheet" type="text/css" media="screen" href="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/ask_float_fonts_css-6b30a53970eb5c3a2a045e3df585b475.css"><div data-mod="popu_64" class="tracking-ad" chg-blk="0"><a id="com-appcode-float-block" href="http://www.csdn.net/app/" target="_blank" title="APP二维码" style="top:188px"><span id="appcode-close"></span></a><a id="com-app-float-block" href="http://www.csdn.net/app/" title="APP下载" style="top:272px"></a><a id="com-quick-reply" title="快速回复" style="top:310px"></a><a id="com-d-top-a" style="top: 348px; display: inline;" title="返回顶部" onclick=""></a> </div><div class="pop_edit ask_second comm_ask_second"><h3>提问</h3><span class="ask_float_span">您的问题将会被发布在“<a class="ask_float_channel" href="http://ask.csdn.net/" target="_blank" style="cursor:pointer">技术问答</a>”频道</span><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" nodetype="close" class="close">×</a><div class="context"><div class="err_div"><span class="err_ico"></span><span class="err_txt">该问题已存在，请勿重复提问</span></div><div class="input_div"><input id="askInputSecond" type="text" style="font-size:14px;" placeholder="问题标题"></div><div class="cm_box"><div class="cm_dialog"></div> <div class="pop_cm cm_add_link"><input type="text" placeholder="链接内容" id="af_cm_link_txt"><input type="text" placeholder="链接地址" id="af_cm_link_url"><input type="text" placeholder="链接提示" id="af_cm_link_tit"><div class="text-right"><span class="btn btn-default btn-sm" id="add_link_btn">插入链接</span> </div> </div><div class="pop_cm cm_add_img"><div class="nav-tabs"><a class="img_tab active" href="http://blog.csdn.net/lufeng20/article/details/24314381#tab_upload">本地上传</a><a class="img_tab" href="http://blog.csdn.net/lufeng20/article/details/24314381#tab_weburl">网络图片</a></div><div class="tab_panel active" id="tab_upload"><div class="set_img"><iframe src="./彻底理解ThreadLocal - 逆风奔跑。。不要去考虑什么天赋异禀，一切都来自经历和渴望。 - 博客频道 - CSDN.NET_files/upload.html"></iframe></div></div><div class="tab_panel" id="tab_weburl"><input type="text" placeholder="图片地址" id="af_cm_img_url"><input type="text" placeholder="图片说明" id="af_cm_img_alt"><div class="text-right"><span class="btn btn-default btn-sm" id="add_img_btn">插入图片</span> </div></div> </div></div> <textarea id="editor_all" rows="8" style="display: none;"></textarea><div class="editor-toolbar"><i class="separator">|</i><a class="icon-headline" title="标题一（Ctrl+Alt+1）"></a><a class="icon-heading" title="标题二（Ctrl+Alt+2）"></a><a class="icon-bold" title="粗体（Ctrl+B）"></a><a class="icon-italic" title="斜体（Ctrl+I）"></a><i class="separator">|</i><a class="icon-quote-left" title="引用（Ctrl+’）"></a><a class="icon-code" title="插入代码片（Ctrl+,）"></a><a class="icon-list-ul" title="无序列表（Ctrl+L）"></a><a class="icon-list-ol" title="有序列表（Ctrl+Alt+L）"></a><i class="separator">|</i><a class="icon-link" title="添加链接（Ctrl+K）"></a><a class="icon-picture" title="添加图片（Ctrl+Alt+I）"></a><i class="separator">|</i><a class="icon-reply" title="撤退（Ctrl+Z）"></a><a class="icon-share-alt" title="前进（Ctrl+Shift+Z）"></a><i class="separator">|</i><a class="icon-info" href="http://ask.csdn.net/pages/markdown" target="_blank" title="markdown语法参考"></a><a class="icon-preview" title="预览"></a><i class="separator">|</i></div><div class="CodeMirror cm-s-paper CodeMirror-focused"><div style="overflow: hidden; position: relative; width: 3px; height: 0px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; padding: 0px; width: 1000px; height: 1em; outline: none; font-size: 4px;"></textarea></div><div class="CodeMirror-hscrollbar"><div style="height: 1px;"></div></div><div class="CodeMirror-vscrollbar"><div style="width: 1px;"></div></div><div class="CodeMirror-scrollbar-filler"></div><div class="CodeMirror-gutter-filler"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="min-width: 33px;"><div style="position: relative;"><div class="CodeMirror-lines"><div style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre>&nbsp;<span style="display: inline-block; width: 1px; margin-right: -1px;">&nbsp;</span></pre></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code"></div><div class="CodeMirror-cursor" style="visibility: hidden;">&nbsp;</div><div class="CodeMirror-cursor CodeMirror-secondarycursor" style="visibility: hidden;">&nbsp;</div></div></div></div></div><div style="position: absolute; height: 30px; width: 1px;"></div><div class="CodeMirror-gutters" style="display: none;"></div></div></div><div class="editor-statusbar"><span class="lines">0</span><span class="words">0</span><span class="cursor">0:0</span></div><div class="div_tags clearfix"><div id="divSearchTags" class="tags_con"><input type="text"></div><input type="hidden" name="txtSearchTags"></div><div id="ask2_tagRecomm_div" class="drt_tagRecomm tracking-ad" data-mod="popu_73"><span class="drt_tit">推荐标签：</span></div></div><div class="success"><div class="left_area"><input id="chk_cb" type="checkbox"><span class="wyxs">我要悬赏</span><input id="cb_num" class="cb_num" readonly="true"><span class="phib_rii"><span> 币</span></span></div><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" nodetype="cancel" class="cancel">取消</a><a href="http://blog.csdn.net/lufeng20/article/details/24314381#" nodetype="ok" class="ok">发布</a></div></div><div id="common_ask_div_sc" class="searchContainer"><div class="sTitle">可能存在类似的问题：</div><div class="sFooter"><a class="sFirstNewAsk">我想提一个新问题</a></div></div></body></html>